diff --git a/Node/cards-RichCards/app.js b/Node/cards-RichCards/app.js index d85bf8acf4..47af53b815 100644 --- a/Node/cards-RichCards/app.js +++ b/Node/cards-RichCards/app.js @@ -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) { diff --git a/Node/core-AppInsights/telemetry-module.js b/Node/core-AppInsights/telemetry-module.js index e0a5376490..f867b2784f 100644 --- a/Node/core-AppInsights/telemetry-module.js +++ b/Node/core-AppInsights/telemetry-module.js @@ -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), diff --git a/Node/core-ChannelData/facebook-channeldata.js b/Node/core-ChannelData/facebook-channeldata.js index f9810a2cce..fb5038aac8 100644 --- a/Node/core-ChannelData/facebook-channeldata.js +++ b/Node/core-ChannelData/facebook-channeldata.js @@ -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 = { @@ -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); }; diff --git a/Node/core-CreateNewConversation/app.js b/Node/core-CreateNewConversation/app.js index d8bb66f5d9..b4c14692d7 100644 --- a/Node/core-CreateNewConversation/app.js +++ b/Node/core-CreateNewConversation/app.js @@ -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() diff --git a/Node/core-DirectLine/DirectLineBot/app.js b/Node/core-DirectLine/DirectLineBot/app.js index d05253857b..6f666a91f8 100644 --- a/Node/core-DirectLine/DirectLineBot/app.js +++ b/Node/core-DirectLine/DirectLineBot/app.js @@ -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) diff --git a/Node/core-DirectLine/DirectLineClient/app.js b/Node/core-DirectLine/DirectLineClient/app.js index bfa52a3315..065e57ae25 100644 --- a/Node/core-DirectLine/DirectLineClient/app.js +++ b/Node/core-DirectLine/DirectLineClient/app.js @@ -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 }); @@ -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> '); } @@ -70,13 +75,13 @@ 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); } @@ -84,7 +89,7 @@ function pollMessages(client, conversationId) { 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(); @@ -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); @@ -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) + '*'); diff --git a/Node/core-DirectLine/README.md b/Node/core-DirectLine/README.md index 32c4baa095..59d1914bf1 100644 --- a/Node/core-DirectLine/README.md +++ b/Node/core-DirectLine/README.md @@ -27,7 +27,7 @@ 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'; @@ -35,41 +35,34 @@ 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 }); @@ -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) { @@ -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); diff --git a/Node/core-GetConversationMembers/README.md b/Node/core-GetConversationMembers/README.md index 96d7f13aed..36ce435526 100644 --- a/Node/core-GetConversationMembers/README.md +++ b/Node/core-GetConversationMembers/README.md @@ -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 + ')'; }) @@ -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 + ')'; }) @@ -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')); @@ -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() diff --git a/Node/core-GetConversationMembers/app.js b/Node/core-GetConversationMembers/app.js index 6a0b3947bc..34f89f49d3 100644 --- a/Node/core-GetConversationMembers/app.js +++ b/Node/core-GetConversationMembers/app.js @@ -8,11 +8,10 @@ var url = require('url'); var Swagger = require('swagger-client'); // Swagger client for Bot Connector API -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 +}); // Setup Restify Server var server = restify.createServer(); @@ -38,21 +37,25 @@ var bot = new builder.UniversalBot(connector, function (session) { // 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) => { + addTokenToClient(connector, connectorApiClient).then(function (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)); + .then(function (res) { + printMembersInChannel(message.address, res.obj); + }) + .catch(function (error) { + console.log('Error retrieving conversation members: ' + error.statusText); + }); }); }); 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 + ')'; }) @@ -65,7 +68,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 + ')'; }) @@ -83,7 +86,7 @@ bot.on('conversationUpdate', function (message) { 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')); @@ -95,7 +98,7 @@ function addTokenToClient(connector, clientPromise) { function printMembersInChannel(conversationAddress, members) { if (!members || members.length === 0) return; - var memberList = members.map((m) => '* ' + m.name + ' (Id: ' + m.id + ')') + var memberList = members.map(function (m) { return '* ' + m.name + ' (Id: ' + m.id + ')'; }) .join('\n '); var reply = new builder.Message() diff --git a/Node/core-MultiDialogs/README.md b/Node/core-MultiDialogs/README.md index 13fbdd4659..653139739b 100644 --- a/Node/core-MultiDialogs/README.md +++ b/Node/core-MultiDialogs/README.md @@ -100,7 +100,7 @@ The last step ends performing an async call to a simulated store, printing the r // Async search Store .searchHotels(destination, checkIn, checkOut) - .then((hotels) => { + .then(function (hotels) { // Results session.send('I found in total %d hotels for your dates:', hotels.length); @@ -168,7 +168,7 @@ Check out [hotels.js](hotels.js#L46-L61) where we are calling an asynchronous me // Async search Store .searchHotels(destination, checkIn, checkOut) - .then((hotels) => { + .then(function (hotels) { // Results session.send('I found in total %d hotels for your dates:', hotels.length); diff --git a/Node/core-MultiDialogs/hotels.js b/Node/core-MultiDialogs/hotels.js index 68a5876713..bcbbe89fa2 100644 --- a/Node/core-MultiDialogs/hotels.js +++ b/Node/core-MultiDialogs/hotels.js @@ -46,7 +46,7 @@ module.exports = [ // Async search Store .searchHotels(destination, checkIn, checkOut) - .then((hotels) => { + .then(function (hotels) { // Results session.send('I found in total %d hotels for your dates:', hotels.length); diff --git a/Node/core-MultiDialogs/store.js b/Node/core-MultiDialogs/store.js index 6a40a64d8f..d619a2f9b8 100644 --- a/Node/core-MultiDialogs/store.js +++ b/Node/core-MultiDialogs/store.js @@ -17,10 +17,10 @@ module.exports = { }); } - hotels.sort((a, b) => a.priceStarting - b.priceStarting); + hotels.sort(function (a, b) { return a.priceStarting - b.priceStarting; }); // complete promise with a timer to simulate async response - setTimeout(() => resolve(hotels), 1000); + setTimeout(function () { resolve(hotels); }, 1000); }); } }; \ No newline at end of file diff --git a/Node/core-SendAttachment/README.md b/Node/core-SendAttachment/README.md index 9dcba14711..eadfbd0120 100644 --- a/Node/core-SendAttachment/README.md +++ b/Node/core-SendAttachment/README.md @@ -36,7 +36,7 @@ data:image/png;base64,iVBORw0KGgo… Checkout [app.js](./app.js#L60-L78) to see how to convert a file read using `fs.readFile()` and then create the message attachment. ````JavaScript -fs.readFile('./images/small-image.png', (err, data) => { +fs.readFile('./images/small-image.png', function (err, data) { var contentType = 'image/png'; var base64 = Buffer.from(data).toString('base64'); @@ -67,7 +67,7 @@ This sample provides a [helper method](./app.js#L128-L176) you can use that enca ````JavaScript // read file content and upload -fs.readFile('./images/big-image.png', (err, data) => { +fs.readFile('./images/big-image.png', function (err, data) { if (err) { return session.send('Oops. Error reading file.'); } @@ -81,7 +81,7 @@ fs.readFile('./images/big-image.png', (err, data) => { connectorApiClient, session.message.address.serviceUrl, session.message.address.conversation.id) - .then(attachmentUrl => { + .then(function (attachmentUrl) { // Send Message with Attachment obj using returned Url var msg = new builder.Message(session) .addAttachment({ @@ -92,7 +92,7 @@ fs.readFile('./images/big-image.png', (err, data) => { session.send(msg); }) - .catch(err => { + .catch(function (err) { console.log('Error uploading file', err); session.send('Oops. Error uploading file. ' + err.message); }); diff --git a/Node/core-SendAttachment/app.js b/Node/core-SendAttachment/app.js index c83a72d6d8..5694bcad0b 100644 --- a/Node/core-SendAttachment/app.js +++ b/Node/core-SendAttachment/app.js @@ -52,14 +52,14 @@ var bot = new builder.UniversalBot(connector, [ } }]); -const Inline = 'Show inline attachment'; -const Upload = 'Show uploaded attachment'; -const External = 'Show Internet attachment'; -const Options = [Inline, Upload, External]; +var Inline = 'Show inline attachment'; +var Upload = 'Show uploaded attachment'; +var External = 'Show Internet attachment'; +var Options = [Inline, Upload, External]; // Sends attachment inline in base64 function sendInline(session, filePath, contentType, attachmentFileName) { - fs.readFile(filePath, (err, data) => { + fs.readFile(filePath, function (err, data) { if (err) { return session.send('Oops. Error reading file.'); } @@ -81,7 +81,7 @@ function sendInline(session, filePath, contentType, attachmentFileName) { function uploadFileAndSend(session, filePath, contentType, attachmentFileName) { // read file content and upload - fs.readFile(filePath, (err, data) => { + fs.readFile(filePath, function (err, data) { if (err) { return session.send('Oops. Error reading file.'); } @@ -95,7 +95,7 @@ function uploadFileAndSend(session, filePath, contentType, attachmentFileName) { connectorApiClient, session.message.address.serviceUrl, session.message.address.conversation.id) - .then(attachmentUrl => { + .then(function (attachmentUrl) { // Send Message with Attachment obj using returned Url var msg = new builder.Message(session) .addAttachment({ @@ -106,7 +106,7 @@ function uploadFileAndSend(session, filePath, contentType, attachmentFileName) { session.send(msg); }) - .catch(err => { + .catch(function (err) { console.log('Error uploading file', err); session.send('Oops. Error uploading file. ' + err.message); }); @@ -135,7 +135,7 @@ function uploadAttachment(fileData, contentType, fileName, connector, connectorA // ask the connector for the token. If it expired, a new token will be requested to the API var obtainToken = Promise.promisify(connector.addAccessToken.bind(connector)); var options = {}; - return Promise.all([clientPromise, obtainToken(options)]).then((values) => { + return Promise.all([clientPromise, obtainToken(options)]).then(function (values) { var client = values[0]; var hasToken = !!options.headers.Authorization; if (hasToken) { @@ -148,7 +148,7 @@ function uploadAttachment(fileData, contentType, fileName, connector, connectorA } // 1. inject the JWT from the connector to the client on every call - return addTokenToClient(connector, connectorApiClient).then((client) => { + return addTokenToClient(connector, connectorApiClient).then(function (client) { // 2. override API client host (api.botframework.com) with channel's serviceHost (e.g.: slack.botframework.com) var serviceUrl = url.parse(baseServiceUrl); var serviceHost = serviceUrl.host; @@ -165,7 +165,7 @@ function uploadAttachment(fileData, contentType, fileName, connector, connectorA }; return client.Conversations.Conversations_UploadAttachment(uploadParameters) - .then((res) => { + .then(function (res) { var attachmentId = res.obj.id; var attachmentUrl = serviceUrl; diff --git a/Node/demo-ContosoFlowers/README.md b/Node/demo-ContosoFlowers/README.md index a0f4f3e8b2..2352792925 100644 --- a/Node/demo-ContosoFlowers/README.md +++ b/Node/demo-ContosoFlowers/README.md @@ -26,7 +26,7 @@ server.post('/api/messages', connector.listen()); In Contoso Flowers, we are wrapping the Connector's `listen()` method in order to capture the web application's url. We'll use this url later to create a link to the ckeckout form. -Checkout [bot/index.js](bot/index.js#L108-L118) to see how to capture the url and [app.js](app.js#L23-L25) to see how to register the hook. +Checkout [bot/index.js](bot/index.js#L108-L118) to see how to capture the url and [app.js](app.js#L27-L29) to see how to register the hook. ````JavaScript // /bot/index.js @@ -55,9 +55,9 @@ Some platforms provide a way to detect when a new conversation with the bot is c ````JavaScript // Send welcome when conversation with bot is started, by initiating the root dialog -bot.on('conversationUpdate', (message) => { +bot.on('conversationUpdate', function (message) { if (message.membersAdded) { - message.membersAdded.forEach((identity) => { + message.membersAdded.forEach(function (identity) { if (identity.id === message.address.bot.id) { bot.beginDialog(message.address, '/'); } @@ -110,7 +110,7 @@ E.g.: To start the shopping's experience root dialog we use `session.beginDialog ````JavaScript // /bot/dialogs/shop.js -const lib = new builder.Library('shop'); +var lib = new builder.Library('shop'); lib.dialog('/', [ function (session) { // Ask for delivery address using 'address' library @@ -133,15 +133,19 @@ Another more common approach for this feature is encapsulating a re-usable dialo This is how you could package an email validation: ````JavaScript -const EmailRegex = new RegExp(/[a-z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/); +var EmailRegex = new RegExp(/[a-z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/); -const library = new builder.Library('validators'); +var lib = new builder.Library('validators'); -library.dialog('email', - builder.DialogAction.validatedPrompt(builder.PromptType.text, (response) => - EmailRegex.test(response))); +lib.dialog('email', + builder.DialogAction.validatedPrompt(builder.PromptType.text, function (response) { + return EmailRegex.test(response); + })); -module.exports = library; +// Export createLibrary() function +module.exports.createLibrary = function () { + return lib.clone(); +}; ```` And this is how you can call the validator from your existing code: @@ -169,7 +173,7 @@ Another example of a reusable library is the [BotBuilder's Location picker contr Checkout the [address dialog](bot/dialogs/address.js#L6-L29) to see its usage within Contoso Flowers. ````JavaScript -const lib = new builder.Library('address'); +var lib = new builder.Library('address'); // Register BotBuilder-Location dialog lib.library(locationDialog.createLibrary(process.env.BING_MAPS_KEY)); @@ -230,7 +234,7 @@ Another example of rich card, is the ReceiptCard which renders differently depen ````JavaScript // Retrieve order and create ReceiptCard -orderService.retrieveOrder(orderId).then((order) => { +orderService.retrieveOrder(orderId).then(function (order) { if (!order) { throw new Error(session.gettext('order_not_found')); } @@ -292,15 +296,17 @@ bot.dialog('/', [ // Create dialog function var displayProducts = CarouselPagination.create( // getPageFunc(pageNumber: number, pageSize: number):Promise - (pageNumber, pageSize) => Products.getProducts(DefaultCategory, pageNumber, pageSize), + function (pageNumber, pageSize) { return Products.getProducts(DefaultCategory, pageNumber, pageSize); }, // getItemFunc(title: string):Promise Products.getProduct, // itemToCardFunc(product: object):object - (product) => ({ - title: product.name, - subtitle: '$ ' + product.price.toFixed(2), - imageUrl: product.imageUrl, - buttonLabel: 'Choose' + function (product) { + return { + title: product.name, + subtitle: '$ ' + product.price.toFixed(2), + imageUrl: product.imageUrl, + buttonLabel: 'Choose' + }; }), // settings { @@ -466,10 +472,10 @@ Additionally, you'll notice the Settings dialog is globally available, meaning t ````JavaScript // Trigger secondary dialogs when 'settings' or 'support' is called -const settingsRegex = /^settings/i; -const supportRegex = new RegExp('^(talk to support|help)', 'i'); +var settingsRegex = /^settings/i; +var supportRegex = new RegExp('^(talk to support|help)', 'i'); bot.use({ - botbuilder: (session, next) => { + botbuilder: function (session, next) { var text = session.message.text; if (settingsRegex.test(text)) { // interrupt and trigger 'settings' dialog @@ -500,7 +506,7 @@ In this sample, the user proceeds to checkout the order by browsing to an url pr var addressSerialized = botUtils.serializeAddress(session.message.address); // Create order (with no payment - pending) -orderService.placePendingOrder(order).then((order) => { +orderService.placePendingOrder(order).then(function (order) { // Build Checkout url using previously stored Site url var checkoutUrl = util.format( @@ -513,7 +519,7 @@ orderService.placePendingOrder(order).then((order) => { }); ```` -Once the user browses to the checkout page and process the payment, the `Address` included in the url is then decoded (using the [deserializeAddress](bot/utils.js#L29) function) and used to resume the conversation with the bot. You can check [express.js Checkout route](checkout.js) calling the [bot.beginDialog()](checkout.js#L64) function. +Once the user browses to the checkout page and process the payment, the `Address` included in the url is then decoded (using the [deserializeAddress](bot/utils.js#L28-L30) function) and used to resume the conversation with the bot. You can check [express.js Checkout route](checkout.js) calling the [bot.beginDialog()](checkout.js#L64) function. > These [helpers methods](bot/utils.js) serialize the address into JSON and then encrypts the string using AES256-CTR to avoid tampering. The inverse process occurs while deserializing the address. @@ -531,7 +537,7 @@ router.post('/', function (req, res, next) { }; // Complete order - orderService.confirmOrder(orderId, paymentDetails).then((processedOrder) => { + orderService.confirmOrder(orderId, paymentDetails).then(function (processedOrder) { // Dispatch completion dialog bot.beginDialog(address, 'checkout:completed', { orderId: orderId }); @@ -598,7 +604,7 @@ You can see in the previous code snippet that we are providing a locale path to Send text: ````JavaScript -bot.dialog("/", function (session) { +bot.dialog('/', function (session) { session.send('welcome_title'); // Will print "Welcome to the Contoso Flowers" session.send('welcome_subtitle'); // Will print "These are the flowers you are looking for!" }); @@ -632,7 +638,7 @@ You can also localize content by using [session.gettext() method](https://docs.b "final_price": "The final price is $%d (including delivery). Pay securely using our payment provider.", } -// bot/dialogs/checout.js#L37 +// bot/dialogs/checkout.js#L37 var messageText = session.gettext('final_price', order.selection.price); var card = new builder.HeroCard(session) .text(messageText); diff --git a/Node/demo-ContosoFlowers/app.js b/Node/demo-ContosoFlowers/app.js index 040d3bd1bb..f68fe030dc 100644 --- a/Node/demo-ContosoFlowers/app.js +++ b/Node/demo-ContosoFlowers/app.js @@ -16,8 +16,9 @@ app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); app.use(express.static(path.join(__dirname, 'public'))); // Register your web app routes here -app.get('/', (req, res, next) => - res.render('index', { title: 'Contoso Flowers' })); +app.get('/', function (req, res, next) { + res.render('index', { title: 'Contoso Flowers' }); +}); // Register Checkout page var checkout = require('./checkout'); diff --git a/Node/demo-ContosoFlowers/bot/dialogs/CarouselPagination.js b/Node/demo-ContosoFlowers/bot/dialogs/CarouselPagination.js index 4d9b7f8adf..9bcaef2619 100644 --- a/Node/demo-ContosoFlowers/bot/dialogs/CarouselPagination.js +++ b/Node/demo-ContosoFlowers/bot/dialogs/CarouselPagination.js @@ -1,6 +1,6 @@ var builder = require('botbuilder'); -const defaultSettings = { +var defaultSettings = { showMoreTitle: 'title_show_more', showMoreValue: 'show_more', selectTemplate: 'select', @@ -57,7 +57,7 @@ module.exports = { } else if (input && isSelection(input, selectPrefix)) { // Validate selection var selectedName = input.substring(selectPrefix.length); - getItemFunc(selectedName).then((selectedItem) => { + getItemFunc(selectedName).then(function (selectedItem) { if (!selectedItem) { return session.send(settings.unknownOption); } @@ -73,14 +73,14 @@ module.exports = { } // retrieve from service and send items - getPageFunc(pageNumber, settings.pageSize).then((pageResult) => { + getPageFunc(pageNumber, settings.pageSize).then(function (pageResult) { // save current page number session.dialogData.pageNumber = pageNumber; // items carousel var cards = pageResult.items .map(itemToCardFunc) - .map((cardData) => asCard(session, cardData)); + .map(function (cardData) { return asCard(session, cardData); }); var message = new builder.Message(session) .attachmentLayout(builder.AttachmentLayout.carousel) .attachments(cards); diff --git a/Node/demo-ContosoFlowers/bot/dialogs/address.js b/Node/demo-ContosoFlowers/bot/dialogs/address.js index d49c3bdad5..140b2a8a98 100644 --- a/Node/demo-ContosoFlowers/bot/dialogs/address.js +++ b/Node/demo-ContosoFlowers/bot/dialogs/address.js @@ -1,7 +1,7 @@ var builder = require('botbuilder'); var locationDialog = require('botbuilder-location'); -const lib = new builder.Library('address'); +var lib = new builder.Library('address'); // Register BotBuilder-Location dialog lib.library(locationDialog.createLibrary(process.env.BING_MAPS_KEY)); @@ -43,11 +43,12 @@ lib.dialog('/', [ // Request Billing Address // Prompt/Save selected address. Uses previous dialog to request and validate address. -const UseSavedInfoChoices = { +var UseSavedInfoChoices = { Home: 'home_address', Work: 'work_address', NotThisTime: 'not_this_time' }; + lib.dialog('billing', [ function (session, args, next) { var selection = session.message.text; diff --git a/Node/demo-ContosoFlowers/bot/dialogs/checkout.js b/Node/demo-ContosoFlowers/bot/dialogs/checkout.js index 677da6aa26..399e87cd53 100644 --- a/Node/demo-ContosoFlowers/bot/dialogs/checkout.js +++ b/Node/demo-ContosoFlowers/bot/dialogs/checkout.js @@ -4,13 +4,13 @@ var botUtils = require('../utils'); var siteUrl = require('../site-url'); var orderService = require('../../services/orders'); -const lib = new builder.Library('checkout'); - // Checkout flow -const RestartMessage = 'restart'; -const StartOver = 'start_over'; -const KeepGoing = 'continue'; -const Help = 'help'; +var RestartMessage = 'restart'; +var StartOver = 'start_over'; +var KeepGoing = 'continue'; +var Help = 'help'; + +var lib = new builder.Library('checkout'); lib.dialog('/', [ function (session, args, next) { args = args || {}; @@ -25,7 +25,7 @@ lib.dialog('/', [ var addressSerialized = botUtils.serializeAddress(session.message.address); // Create order (with no payment - pending) - orderService.placePendingOrder(order).then((order) => { + orderService.placePendingOrder(order).then(function (order) { // Build Checkout url using previously stored Site url var checkoutUrl = util.format( @@ -48,7 +48,7 @@ lib.dialog('/', [ }, function (session, args) { builder.Prompts.choice(session, 'select_how_to_continue', [ - session.gettext(StartOver), + session.gettext(StartOver), session.gettext(KeepGoing), session.gettext(Help) ]); @@ -71,7 +71,7 @@ lib.dialog('completed', function (session, args, next) { var orderId = args.orderId; // Retrieve order and create ReceiptCard - orderService.retrieveOrder(orderId).then((order) => { + orderService.retrieveOrder(orderId).then(function (order) { if (!order) { throw new Error(session.gettext('order_not_found')); } @@ -104,7 +104,7 @@ lib.dialog('completed', function (session, args, next) { .addAttachment(receiptCard); session.endDialog(message); - }).catch((err) => { + }).catch(function (err) { session.endDialog(session.gettext('error_ocurred', err.message)); }); }); diff --git a/Node/demo-ContosoFlowers/bot/dialogs/delivery.js b/Node/demo-ContosoFlowers/bot/dialogs/delivery.js index e43056bab5..42c924a873 100644 --- a/Node/demo-ContosoFlowers/bot/dialogs/delivery.js +++ b/Node/demo-ContosoFlowers/bot/dialogs/delivery.js @@ -1,9 +1,9 @@ var builder = require('botbuilder'); -const Today = 'today'; -const Tomorrow = 'tomorrow'; +var Today = 'today'; +var Tomorrow = 'tomorrow'; -const lib = new builder.Library('delivery'); +var lib = new builder.Library('delivery'); lib.dialog('date', [ function (session, args, next) { builder.Prompts.choice(session, 'choose_delivery_date', [ diff --git a/Node/demo-ContosoFlowers/bot/dialogs/details.js b/Node/demo-ContosoFlowers/bot/dialogs/details.js index 631ecf7583..4c4ecf47cd 100644 --- a/Node/demo-ContosoFlowers/bot/dialogs/details.js +++ b/Node/demo-ContosoFlowers/bot/dialogs/details.js @@ -1,7 +1,7 @@ var util = require('util'); var builder = require('botbuilder'); -const lib = new builder.Library('details'); +var lib = new builder.Library('details'); // Recipient & Sender details lib.dialog('/', [ @@ -48,7 +48,7 @@ lib.dialog('/', [ ]); // Sender details -const UseSavedInfoChoices = { +var UseSavedInfoChoices = { Yes: 'yes', No: 'edit' }; diff --git a/Node/demo-ContosoFlowers/bot/dialogs/help.js b/Node/demo-ContosoFlowers/bot/dialogs/help.js index e3bc85c544..4f45435654 100644 --- a/Node/demo-ContosoFlowers/bot/dialogs/help.js +++ b/Node/demo-ContosoFlowers/bot/dialogs/help.js @@ -1,6 +1,6 @@ var builder = require('botbuilder'); -const lib = new builder.Library('help'); +var lib = new builder.Library('help'); lib.dialog('/', builder.DialogAction.endDialog('thank_you')); // Export createLibrary() function diff --git a/Node/demo-ContosoFlowers/bot/dialogs/product-selection.js b/Node/demo-ContosoFlowers/bot/dialogs/product-selection.js index 55ed59c7d5..f2e2eac267 100644 --- a/Node/demo-ContosoFlowers/bot/dialogs/product-selection.js +++ b/Node/demo-ContosoFlowers/bot/dialogs/product-selection.js @@ -12,7 +12,7 @@ var carouselOptions = { unknownOption: 'unknown_option' }; -const lib = new builder.Library('product-selection'); +var lib = new builder.Library('product-selection'); // These steps are defined as a waterfall dialog, // but the control is done manually by calling the next func argument. @@ -37,7 +37,7 @@ lib.dialog('/', function (session, args, next) { var categoryName = session.dialogData.category.name; CarouselPagination.create( - (pageNumber, pageSize) => products.getProducts(categoryName, pageNumber, pageSize), + function (pageNumber, pageSize) { return products.getProducts(categoryName, pageNumber, pageSize); }, products.getProduct, productMapping, carouselOptions diff --git a/Node/demo-ContosoFlowers/bot/dialogs/settings.js b/Node/demo-ContosoFlowers/bot/dialogs/settings.js index 8c2dfb8de5..66cb14f097 100644 --- a/Node/demo-ContosoFlowers/bot/dialogs/settings.js +++ b/Node/demo-ContosoFlowers/bot/dialogs/settings.js @@ -4,7 +4,7 @@ var validators = require('../validators'); var utils = require('../utils'); var addressLibrary = require('./address'); -const SettingChoice = { +var SettingChoice = { Email: 'edit_email', Phone: 'edit_phone', Addresses: 'edit_addresses', @@ -63,18 +63,18 @@ lib.dialog('/', [ // Email edit lib.dialog('email', editOptionDialog( - (input) => validators.EmailRegex.test(input), + function (input) { return validators.EmailRegex.test(input); }, 'invalid_email_address', - (session, email) => saveSenderSetting(session, 'email', email))); + function (session, email) { saveSenderSetting(session, 'email', email); })); // Phone Number edit lib.dialog('phone', editOptionDialog( - (input) => validators.PhoneRegex.test(input), + function (input) { return validators.PhoneRegex.test(input); }, 'invalid_phone_number', - (session, phone) => saveSenderSetting(session, 'phoneNumber', phone))); + function (session, phone) { saveSenderSetting(session, 'phoneNumber', phone); })); // Addresses -const UseSavedInfoChoices = addressLibrary.UseSavedInfoChoices; +var UseSavedInfoChoices = addressLibrary.UseSavedInfoChoices; lib.dialog('addresses', [ function (session, args, next) { diff --git a/Node/demo-ContosoFlowers/bot/dialogs/shop.js b/Node/demo-ContosoFlowers/bot/dialogs/shop.js index 5e2f7aa367..d7fef7d564 100644 --- a/Node/demo-ContosoFlowers/bot/dialogs/shop.js +++ b/Node/demo-ContosoFlowers/bot/dialogs/shop.js @@ -1,7 +1,7 @@ var util = require('util'); var builder = require('botbuilder'); -const lib = new builder.Library('shop'); +var lib = new builder.Library('shop'); lib.dialog('/', [ function (session) { // Ask for delivery address using 'address' library diff --git a/Node/demo-ContosoFlowers/bot/index.js b/Node/demo-ContosoFlowers/bot/index.js index d95c2e892b..c36c24b8b1 100644 --- a/Node/demo-ContosoFlowers/bot/index.js +++ b/Node/demo-ContosoFlowers/bot/index.js @@ -7,12 +7,12 @@ var connector = new builder.ChatConnector({ }); // Welcome Dialog -const MainOptions = { +var MainOptions = { Shop: 'main_options_order_flowers', Support: 'main_options_talk_to_support' }; -var bot = new builder.UniversalBot(connector, (session) => { +var bot = new builder.UniversalBot(connector, function (session) { if (localizedRegex(session, [MainOptions.Shop]).test(session.message.text)) { // Order Flowers @@ -60,7 +60,7 @@ bot.library(require('./validators').createLibrary()); // Trigger secondary dialogs when 'settings' or 'support' is called bot.use({ - botbuilder: (session, next) => { + botbuilder: function (session, next) { var text = session.message.text; var settingsRegex = localizedRegex(session, ['main_options_settings']); @@ -80,9 +80,9 @@ bot.use({ }); // Send welcome when conversation with bot is started, by initiating the root dialog -bot.on('conversationUpdate', (message) => { +bot.on('conversationUpdate', function (message) { if (message.membersAdded) { - message.membersAdded.forEach((identity) => { + message.membersAdded.forEach(function (identity) { if (identity.id === message.address.bot.id) { bot.beginDialog(message.address, '/'); } @@ -91,7 +91,7 @@ bot.on('conversationUpdate', (message) => { }); // Cache of localized regex to match selection from main options -const LocalizedRegexCache = {}; +var LocalizedRegexCache = {}; function localizedRegex(session, localeKeys) { var locale = session.preferredLocale(); var cacheKey = locale + ":" + localeKeys.join('|'); @@ -99,7 +99,7 @@ function localizedRegex(session, localeKeys) { return LocalizedRegexCache[cacheKey]; } - var localizedStrings = localeKeys.map(key => session.localizer.gettext(locale, key)); + var localizedStrings = localeKeys.map(function (key) { return session.localizer.gettext(locale, key); }); var regex = new RegExp('^(' + localizedStrings.join('|') + ')', 'i'); LocalizedRegexCache[cacheKey] = regex; return regex; diff --git a/Node/demo-ContosoFlowers/bot/site-url.js b/Node/demo-ContosoFlowers/bot/site-url.js index ecc1198726..8144a3db9f 100644 --- a/Node/demo-ContosoFlowers/bot/site-url.js +++ b/Node/demo-ContosoFlowers/bot/site-url.js @@ -1,6 +1,6 @@ // This module provides a singleton store for saving the Site's hosted url var siteUrl = null; module.exports = { - save: (url) => siteUrl = url, - retrieve: () => siteUrl + save: function (url) { siteUrl = url; }, + retrieve: function () { return siteUrl; } }; \ No newline at end of file diff --git a/Node/demo-ContosoFlowers/bot/utils.js b/Node/demo-ContosoFlowers/bot/utils.js index 32bae2a11e..87529a84fe 100644 --- a/Node/demo-ContosoFlowers/bot/utils.js +++ b/Node/demo-ContosoFlowers/bot/utils.js @@ -25,6 +25,10 @@ function descrypt(cryptedInput) { } module.exports = { - serializeAddress: (address) => encrypt(serializeAddress(address)), - deserializeAddress: (input) => deserializeAddress(descrypt(input)) + serializeAddress: function (address) { + return encrypt(serializeAddress(address)); + }, + deserializeAddress: function (input) { + return deserializeAddress(descrypt(input)); + } }; \ No newline at end of file diff --git a/Node/demo-ContosoFlowers/bot/validators.js b/Node/demo-ContosoFlowers/bot/validators.js index b9c7b1d032..8e620eab79 100644 --- a/Node/demo-ContosoFlowers/bot/validators.js +++ b/Node/demo-ContosoFlowers/bot/validators.js @@ -1,21 +1,24 @@ var builder = require('botbuilder'); -const PhoneRegex = new RegExp(/^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$/); -const EmailRegex = new RegExp(/[a-z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/); +var PhoneRegex = new RegExp(/^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$/); +var EmailRegex = new RegExp(/[a-z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/); -const lib = new builder.Library('validators'); +var lib = new builder.Library('validators'); lib.dialog('notes', - builder.DialogAction.validatedPrompt(builder.PromptType.text, (response) => - response && response.length <= 200)); + builder.DialogAction.validatedPrompt(builder.PromptType.text, function (response) { + return response && response.length <= 200; + })); lib.dialog('phonenumber', - builder.DialogAction.validatedPrompt(builder.PromptType.text, (response) => - PhoneRegex.test(response))); + builder.DialogAction.validatedPrompt(builder.PromptType.text, function (response) { + return PhoneRegex.test(response); + })); lib.dialog('email', - builder.DialogAction.validatedPrompt(builder.PromptType.text, (response) => - EmailRegex.test(response))); + builder.DialogAction.validatedPrompt(builder.PromptType.text, function (response) { + return EmailRegex.test(response); + })); // Export createLibrary() function module.exports.createLibrary = function () { diff --git a/Node/demo-ContosoFlowers/checkout.js b/Node/demo-ContosoFlowers/checkout.js index 7b85b0d4d1..fea4858780 100644 --- a/Node/demo-ContosoFlowers/checkout.js +++ b/Node/demo-ContosoFlowers/checkout.js @@ -13,7 +13,7 @@ router.get('/', function (req, res, next) { var address = botUtils.deserializeAddress(req.query.address); console.log('user address is', address); - orderService.retrieveOrder(orderId).then((order) => { + orderService.retrieveOrder(orderId).then(function (order) { // Check order exists if (!order) { throw new Error('Order ID not found'); @@ -38,7 +38,7 @@ router.get('/', function (req, res, next) { order: order }); - }).catch((err) => { + }).catch(function (err) { next(err); }); @@ -58,7 +58,7 @@ router.post('/', function (req, res, next) { }; // Complete order - orderService.confirmOrder(orderId, paymentDetails).then((processedOrder) => { + orderService.confirmOrder(orderId, paymentDetails).then(function (processedOrder) { // Dispatch completion dialog bot.beginDialog(address, 'checkout:completed', { orderId: orderId }); @@ -69,7 +69,7 @@ router.post('/', function (req, res, next) { order: processedOrder }); - }).catch((err) => { + }).catch(function (err) { next(err); }); }); diff --git a/Node/demo-ContosoFlowers/data/orders.json b/Node/demo-ContosoFlowers/data/orders.json index 0637a088a0..2b113c77aa 100644 --- a/Node/demo-ContosoFlowers/data/orders.json +++ b/Node/demo-ContosoFlowers/data/orders.json @@ -1 +1 @@ -[] \ No newline at end of file +[{"selection":{"name":"Bouquet 7™","imageUrl":"https://placeholdit.imgix.net/~text?txtsize=48&txt=Bouquet%207&w=640&h=330","price":90.99},"delivery":{"date":"2017-02-25T00:25:58.683Z","address":"3 de Febrero 2274, Buenos Aires, Argentina"},"details":{"recipient":{"firstName":"Romina","lastName":"Roux","phoneNumber":"111 222 3334"},"note":"TE AMO!","sender":{"email":"sixdemons@gmail.com","phoneNumber":"222 333 4445"}},"billingAddress":"3 de Febrero 2274, Buenos Aires City, Buenos Aires Autonomous City, 1428, Argentina","id":"e81ef3f0-fa27-11e6-b3a7-cb0d0ff30fae","payed":true,"paymentDetails":{"creditcardNumber":"1111 111","creditcardHolder":"asdasd"}}] \ No newline at end of file diff --git a/Node/demo-ContosoFlowers/services/orders.js b/Node/demo-ContosoFlowers/services/orders.js index e458b575c9..b60024127c 100644 --- a/Node/demo-ContosoFlowers/services/orders.js +++ b/Node/demo-ContosoFlowers/services/orders.js @@ -3,7 +3,7 @@ var fs = require('fs'); var _ = require('lodash'); var Promise = require('bluebird'); -const OrderService = { +var OrderService = { placePendingOrder: function (order) { order.id = uuid.v1(); order.payed = false; diff --git a/Node/demo-ContosoFlowers/services/products.js b/Node/demo-ContosoFlowers/services/products.js index 986db99370..db7be522b2 100644 --- a/Node/demo-ContosoFlowers/services/products.js +++ b/Node/demo-ContosoFlowers/services/products.js @@ -1,20 +1,24 @@ var _ = require('lodash'); var Promise = require('bluebird'); -const allCategories = _.times(5) - .map((i) => ({ - name: 'Flower ' + (i + 1), - imageUrl: 'https://placeholdit.imgix.net/~text?txtsize=48&txt=Flower%20' + (i + 1) + '&w=640&h=330' - })); - -const allProducts = _.times(17) - .map((i) => ({ - name: 'Bouquet ' + (i + 1) + '\u2122', - imageUrl: 'https://placeholdit.imgix.net/~text?txtsize=48&txt=Bouquet%20' + (i + 1) + '&w=640&h=330', - price: Math.floor(Math.random() * 100) + 10 + .99 - })); - -const productsService = { +var allCategories = _.times(5) + .map(function (i) { + return { + name: 'Flower ' + (i + 1), + imageUrl: 'https://placeholdit.imgix.net/~text?txtsize=48&txt=Flower%20' + (i + 1) + '&w=640&h=330' + }; + }); + +var allProducts = _.times(17) + .map(function (i) { + return { + name: 'Bouquet ' + (i + 1) + '\u2122', + imageUrl: 'https://placeholdit.imgix.net/~text?txtsize=48&txt=Bouquet%20' + (i + 1) + '&w=640&h=330', + price: Math.floor(Math.random() * 100) + 10 + .99 + }; + }); + +var productsService = { // Categories getCategories: function (pageNumber, pageSize) { return pageItems(pageNumber, pageSize, allCategories); diff --git a/Node/demo-Search/JobListingBot/app.js b/Node/demo-Search/JobListingBot/app.js index 27c26f64b8..6ff335eef3 100644 --- a/Node/demo-Search/JobListingBot/app.js +++ b/Node/demo-Search/JobListingBot/app.js @@ -34,13 +34,13 @@ var bot = new builder.UniversalBot(connector, [ function (session, args) { // trigger Search dialog root, using the generated Query created by /refine var query = args.query; - SearchLibrary.begin(session, { query }); + SearchLibrary.begin(session, { query: query }); }, function (session, args) { // Process selected search results session.send( 'Done! For future reference, you selected these job listings: %s', - args.selection.map(i => i.key).join(', ')); + args.selection.map(function (i) { return i.key; }).join(', ')); } ]); @@ -51,7 +51,7 @@ var jobsResultsMapper = SearchLibrary.defaultResultsMapper(jobToSearchHit); // Register Search Dialogs Library with bot bot.library(SearchLibrary.create({ multipleSelection: true, - search: (query) => azureSearchClient.search(query).then(jobsResultsMapper), + search: function (query) { return azureSearchClient.search(query).then(jobsResultsMapper); }, refiners: ['business_title', 'agency', 'work_location'] })); diff --git a/Node/demo-Search/README.md b/Node/demo-Search/README.md index a5a018d098..3717bc63d7 100644 --- a/Node/demo-Search/README.md +++ b/Node/demo-Search/README.md @@ -74,7 +74,7 @@ In order to use the library you need to create an instance of it using the modul var SearchLibrary = require('./SearchDialogLibrary'); var mySearchLibrary = SearchLibrary.create({ multipleSelection: true, - search: (query) => { return mySearchClient.search(query).then(mapResultSetFunction); }, + search: function (query) { return mySearchClient.search(query).then(mapResultSetFunction); }, refiners: ['type', 'region'] }); @@ -90,7 +90,7 @@ bot.dialog('/', [ // Display selected results session.send( 'Done! You selected these items: %s', - args.selection.map(i => i.title).join(', ')); + args.selection.map(function (i) { return i.title; }).join(', ')); } ]); ```` diff --git a/Node/demo-Search/RealEstateBot/app.js b/Node/demo-Search/RealEstateBot/app.js index d3f92c5c6c..28a2ca8341 100644 --- a/Node/demo-Search/RealEstateBot/app.js +++ b/Node/demo-Search/RealEstateBot/app.js @@ -30,7 +30,7 @@ var bot = new builder.UniversalBot(connector, [ // Process selected search results session.send( 'Done! For future reference, you selected these properties: %s', - args.selection.map(i => i.key).join(', ')); + args.selection.map(function (i) { return i.key; }).join(', ')); } ]); @@ -41,12 +41,13 @@ var realStateResultsMapper = SearchLibrary.defaultResultsMapper(realstateToSearc // Register Search Dialogs Library with bot bot.library(SearchLibrary.create({ multipleSelection: true, - search: (query) => azureSearchClient.search(query).then(realStateResultsMapper), + search: function (query) { return azureSearchClient.search(query).then(realStateResultsMapper); }, refiners: ['region', 'city', 'type'], - refineFormatter: (refiners) => - _.zipObject( - refiners.map(r => 'By ' + _.capitalize(r)), - refiners) + refineFormatter: function (refiners) { + return _.zipObject( + refiners.map(function (r) { return 'By ' + _.capitalize(r); }), + refiners); + } })); // Maps the AzureSearch RealState Document into a SearchHit that the Search Library can use diff --git a/Node/demo-Search/SearchProviders/azure-search.js b/Node/demo-Search/SearchProviders/azure-search.js index 795c2840fd..b75a3fb46c 100644 --- a/Node/demo-Search/SearchProviders/azure-search.js +++ b/Node/demo-Search/SearchProviders/azure-search.js @@ -12,7 +12,7 @@ function create(serviceName, serviceKey, index) { return { search: function (query) { - return new Promise((resolve, reject) => { + return new Promise(function (resolve, reject) { console.log('AzureSearch.inputQuery:', query); // create request & azure query @@ -35,7 +35,7 @@ function create(serviceName, serviceKey, index) { }; console.log('AzureSearch.query:', options.body); - request.post(options, (err, httpResponse, azureResponse) => { + request.post(options, function (err, httpResponse, azureResponse) { if (err) { return reject(err); } @@ -58,8 +58,8 @@ function getFacets(azureResponse) { } var facets = _.toPairs(rawFacets) - .filter(p => _.isArray(p[1])) - .map(p => ({ key: p[0], options: p[1] })); + .filter(function (p) { return _.isArray(p[1]); }) + .map(function (p) { return { key: p[0], options: p[1] }; }); return facets; } @@ -69,8 +69,9 @@ function createFilterParams(filters) { return ''; } - return filters.map((f) => util.format('%s eq \'%s\'', f.key, escapeFilterString(f.value))) - .join(' and '); + return filters.map(function (f) { + return util.format('%s eq \'%s\'', f.key, escapeFilterString(f.value)); + }).join(' and '); } function escapeFilterString(string) { diff --git a/Node/demo-Search/SearchProviders/mock-search.js b/Node/demo-Search/SearchProviders/mock-search.js index 089612caac..d3f76c1aab 100644 --- a/Node/demo-Search/SearchProviders/mock-search.js +++ b/Node/demo-Search/SearchProviders/mock-search.js @@ -2,11 +2,11 @@ var _ = require('lodash'); var uuid = require('node-uuid'); var loremIpsum = require('lorem-ipsum'); -const Refiners = ['region', 'type']; +var Refiners = ['region', 'type']; function refineFormatter(refiners) { return _.zipObject( - refiners.map(r => 'By ' + _.capitalize(r)), + refiners.map(function (r) { return 'By ' + _.capitalize(r); }), refiners); } diff --git a/Node/intelligence-ImageCaption/README.md b/Node/intelligence-ImageCaption/README.md index 4db95c430c..99a8a4ee41 100644 --- a/Node/intelligence-ImageCaption/README.md +++ b/Node/intelligence-ImageCaption/README.md @@ -27,11 +27,11 @@ In this sample we are using the API to get the image description and send it bac ````JavaScript if (hasImageAttachment(session)) { - var stream = needle.get(session.message.attachments[0].contentUrl); + var stream = getImageStreamFromMessage(session.message); captionService .getCaptionFromStream(stream) - .then(caption => handleSuccessResponse(session, caption)) - .catch(error => handleErrorResponse(session, error)); + .then(function (caption) { handleSuccessResponse(session, caption); }) + .catch(function (error) { handleErrorResponse(session, error); }); } ```` @@ -43,16 +43,16 @@ And here is the implementation of `captionService.getCaptionFromStream(stream)` * @param {stream} stream The stream to an image. * @return {Promise} Promise with caption string if succeeded, error otherwise */ -exports.getCaptionFromStream = stream => { +exports.getCaptionFromStream = function (stream) { return new Promise( - (resolve, reject) => { - const requestData = { + function (resolve, reject) { + var requestData = { url: VISION_URL, encoding: 'binary', headers: { 'content-type': 'application/octet-stream' } }; - stream.pipe(request.post(requestData, (error, response, body) => { + stream.pipe(request.post(requestData, function (error, response, body) { if (error) { reject(error); } diff --git a/Node/intelligence-ImageCaption/app.js b/Node/intelligence-ImageCaption/app.js index d7724606cc..9e08940fab 100644 --- a/Node/intelligence-ImageCaption/app.js +++ b/Node/intelligence-ImageCaption/app.js @@ -5,25 +5,25 @@ An image caption bot for the Microsoft Bot Framework. // This loads the environment variables from the .env file require('dotenv-extended').load(); -const builder = require('botbuilder'), - captionService = require('./caption-service'), +var builder = require('botbuilder'), needle = require('needle'), restify = require('restify'), - url = require('url'); -validUrl = require('valid-url'); + url = require('url'), + validUrl = require('valid-url'), + captionService = require('./caption-service'); //========================================================= // Bot Setup //========================================================= // Setup Restify Server -const server = restify.createServer(); +var server = restify.createServer(); server.listen(process.env.port || process.env.PORT || 3978, function () { console.log('%s listening to %s', server.name, server.url); }); // Create chat bot -const connector = new builder.ChatConnector({ +var connector = new builder.ChatConnector({ appId: process.env.MICROSOFT_APP_ID, appPassword: process.env.MICROSOFT_APP_PASSWORD }); @@ -31,20 +31,20 @@ const connector = new builder.ChatConnector({ server.post('/api/messages', connector.listen()); // Gets the caption by checking the type of the image (stream vs URL) and calling the appropriate caption service method. -const bot = new builder.UniversalBot(connector, function (session) { +var bot = new builder.UniversalBot(connector, function (session) { if (hasImageAttachment(session)) { var stream = getImageStreamFromMessage(session.message); captionService .getCaptionFromStream(stream) - .then(caption => handleSuccessResponse(session, caption)) - .catch(error => handleErrorResponse(session, error)); + .then(function (caption) { handleSuccessResponse(session, caption); }) + .catch(function (error) { handleErrorResponse(session, error); }); } else { var imageUrl = parseAnchorTag(session.message.text) || (validUrl.isUri(session.message.text) ? session.message.text : null); if (imageUrl) { captionService .getCaptionFromUrl(imageUrl) - .then(caption => handleSuccessResponse(session, caption)) - .catch(error => handleErrorResponse(session, error)); + .then(function (caption) { handleSuccessResponse(session, caption); }) + .catch(function (error) { handleErrorResponse(session, error); }); } else { session.send('Did you upload an image? I\'m more of a visual person. Try sending me an image or an image URL'); } @@ -60,7 +60,7 @@ bot.on('conversationUpdate', function (message) { if (message.membersAdded) { message.membersAdded.forEach(function (identity) { if (identity.id === message.address.bot.id) { - const reply = new builder.Message() + var reply = new builder.Message() .address(message.address) .text('Hi! I am ImageCaption Bot. I can understand the content of any image and try to describe it as well as any human. Try sending me an image or an image URL.'); bot.send(reply); @@ -73,19 +73,19 @@ bot.on('conversationUpdate', function (message) { //========================================================= // Utilities //========================================================= -const hasImageAttachment = session => { +function hasImageAttachment(session) { return session.message.attachments.length > 0 && session.message.attachments[0].contentType.indexOf('image') !== -1; -}; +} -const getImageStreamFromMessage = message => { +function getImageStreamFromMessage(message) { var headers = {}; var attachment = message.attachments[0]; if (checkRequiresToken(message)) { // The Skype attachment URLs are secured by JwtToken, // you should set the JwtToken of your bot as the authorization header for the GET request your bot initiates to fetch the image. // https://github.com/Microsoft/BotBuilder/issues/662 - connector.getAccessToken((error, token) => { + connector.getAccessToken(function (error, token) { var tok = token; headers['Authorization'] = 'Bearer ' + token; headers['Content-Type'] = 'application/octet-stream'; @@ -96,7 +96,7 @@ const getImageStreamFromMessage = message => { headers['Content-Type'] = attachment.contentType; return needle.get(attachment.contentUrl, { headers: headers }); -}; +} function checkRequiresToken(message) { return message.source === 'skype' || message.source === 'msteams'; @@ -108,19 +108,19 @@ function checkRequiresToken(message) { * @param {string} input Anchor Tag * @return {string} Url matched or null */ -const parseAnchorTag = input => { +function parseAnchorTag(input) { var match = input.match('^[^<]*$'); if (match && match[1]) { return match[1]; } return null; -}; +} //========================================================= // Response Handling //========================================================= -const handleSuccessResponse = (session, caption) => { +function handleSuccessResponse(session, caption) { if (caption) { session.send('I think it\'s ' + caption); } @@ -128,9 +128,9 @@ const handleSuccessResponse = (session, caption) => { session.send('Couldn\'t find a caption for this one'); } -}; +} -const handleErrorResponse = (session, error) => { +function handleErrorResponse(session, error) { session.send('Oops! Something went wrong. Try again later.'); console.error(error); -}; \ No newline at end of file +} \ No newline at end of file diff --git a/Node/intelligence-ImageCaption/caption-service.js b/Node/intelligence-ImageCaption/caption-service.js index 12057b334e..19c046e42e 100644 --- a/Node/intelligence-ImageCaption/caption-service.js +++ b/Node/intelligence-ImageCaption/caption-service.js @@ -3,25 +3,25 @@ // the confidence score of the caption. For more info checkout the API documentation: // https://www.microsoft.com/cognitive-services/en-us/Computer-Vision-API/documentation/AnalyzeImage -const request = require('request').defaults({ encoding: null }); +var request = require('request').defaults({ encoding: null }); -const VISION_URL = 'https://api.projectoxford.ai/vision/v1.0/analyze/?visualFeatures=Description&form=BCSIMG&subscription-key=' + process.env.MICROSOFT_VISION_API_KEY; +var VISION_URL = 'https://api.projectoxford.ai/vision/v1.0/analyze/?visualFeatures=Description&form=BCSIMG&subscription-key=' + process.env.MICROSOFT_VISION_API_KEY; /** * Gets the caption of the image from an image stream * @param {stream} stream The stream to an image. * @return {Promise} Promise with caption string if succeeded, error otherwise */ -exports.getCaptionFromStream = stream => { +exports.getCaptionFromStream = function (stream) { return new Promise( - (resolve, reject) => { - const requestData = { + function (resolve, reject) { + var requestData = { url: VISION_URL, encoding: 'binary', headers: { 'content-type': 'application/octet-stream' } }; - stream.pipe(request.post(requestData, (error, response, body) => { + stream.pipe(request.post(requestData, function (error, response, body) { if (error) { reject(error); } @@ -41,15 +41,15 @@ exports.getCaptionFromStream = stream => { * @param {string} url The URL to an image. * @return {Promise} Promise with caption string if succeeded, error otherwise */ -exports.getCaptionFromUrl = url => { +exports.getCaptionFromUrl = function (url) { return new Promise( - (resolve, reject) => { - const requestData = { + function (resolve, reject) { + var requestData = { url: VISION_URL, json: { 'url': url } }; - request.post(requestData, (error, response, body) => { + request.post(requestData, function (error, response, body) { if (error) { reject(error); } @@ -69,10 +69,10 @@ exports.getCaptionFromUrl = url => { * @param {Object} body Response of the Vision API * @return {string} Description if caption found, null otherwise. */ -const extractCaption = body => { +function extractCaption(body) { if (body && body.description && body.description.captions && body.description.captions.length) { return body.description.captions[0].text; } return null; -}; \ No newline at end of file +} \ No newline at end of file diff --git a/Node/intelligence-LUIS/README.md b/Node/intelligence-LUIS/README.md index 2ace7eaf99..2480895369 100644 --- a/Node/intelligence-LUIS/README.md +++ b/Node/intelligence-LUIS/README.md @@ -130,7 +130,7 @@ bot.dialog('SearchHotels', [ // Async search Store .searchHotels(destination) - .then((hotels) => { + .then(function (hotels) { // args session.send('I found %d hotels:', hotels.length); @@ -161,7 +161,7 @@ bot.dialog('ShowHotelsReviews', function (session, args) { if (hotelEntity) { session.send('Looking for reviews of \'%s\'...', hotelEntity.entity); Store.searchHotelReviews(hotelEntity.entity) - .then((reviews) => { + .then(function (reviews) { var message = new builder.Message() .attachmentLayout(builder.AttachmentLayout.carousel) .attachments(reviews.map(reviewAsAttachment)); @@ -191,11 +191,11 @@ if (process.env.IS_SPELL_CORRECTION_ENABLED === 'true') { botbuilder: function (session, next) { spellService .getCorrectedText(session.message.text) - .then(text => { + .then(function (text) { session.message.text = text; next(); }) - .catch((error) => { + .catch(function (error) { console.error(error); next(); }); diff --git a/Node/intelligence-LUIS/app.js b/Node/intelligence-LUIS/app.js index dbbaa91a4a..f092632ad2 100644 --- a/Node/intelligence-LUIS/app.js +++ b/Node/intelligence-LUIS/app.js @@ -62,7 +62,7 @@ bot.dialog('SearchHotels', [ // Async search Store .searchHotels(destination) - .then((hotels) => { + .then(function (hotels) { // args session.send('I found %d hotels:', hotels.length); @@ -89,7 +89,7 @@ bot.dialog('ShowHotelsReviews', function (session, args) { if (hotelEntity) { session.send('Looking for reviews of \'%s\'...', hotelEntity.entity); Store.searchHotelReviews(hotelEntity.entity) - .then((reviews) => { + .then(function (reviews) { var message = new builder.Message() .attachmentLayout(builder.AttachmentLayout.carousel) .attachments(reviews.map(reviewAsAttachment)); @@ -112,11 +112,11 @@ if (process.env.IS_SPELL_CORRECTION_ENABLED === 'true') { botbuilder: function (session, next) { spellService .getCorrectedText(session.message.text) - .then(text => { + .then(function (text) { session.message.text = text; next(); }) - .catch((error) => { + .catch(function (error) { console.error(error); next(); }); diff --git a/Node/intelligence-LUIS/spell-service.js b/Node/intelligence-LUIS/spell-service.js index 1e59655771..27a49151f2 100644 --- a/Node/intelligence-LUIS/spell-service.js +++ b/Node/intelligence-LUIS/spell-service.js @@ -1,21 +1,21 @@ // The exported functions in this module makes a call to Bing Spell Check API that returns spelling corrections. // For more info, check out the API reference: // https://dev.cognitive.microsoft.com/docs/services/56e73033cf5ff80c2008c679/operations/56e73036cf5ff81048ee6727 -const request = require('request'); +var request = require('request'); -const SPELL_CHECK_API_URL = 'https://api.cognitive.microsoft.com/bing/v5.0/spellcheck/?form=BCSSCK', - SPELL_CHECK_API_KEY = process.env.BING_SPELL_CHECK_API_KEY; +var SPELL_CHECK_API_URL = 'https://api.cognitive.microsoft.com/bing/v5.0/spellcheck/?form=BCSSCK', + SPELL_CHECK_API_KEY = process.env.BING_SPELL_CHECK_API_KEY; /** * Gets the correct spelling for the given text * @param {string} text The text to be corrected * @returns {Promise} Promise with corrected text if succeeded, error otherwise. */ -exports.getCorrectedText = text => { +exports.getCorrectedText = function (text) { return new Promise( - (resolve, reject) => { + function (resolve, reject) { if (text) { - const requestData = { + var requestData = { url: SPELL_CHECK_API_URL, headers: { "Ocp-Apim-Subscription-Key": SPELL_CHECK_API_KEY @@ -26,7 +26,7 @@ exports.getCorrectedText = text => { json: true } - request.post(requestData, (error, response, body) => { + request.post(requestData, function (error, response, body) { if (error) { reject(error); } diff --git a/Node/intelligence-LUIS/store.js b/Node/intelligence-LUIS/store.js index c58a21e38f..82d4710ce7 100644 --- a/Node/intelligence-LUIS/store.js +++ b/Node/intelligence-LUIS/store.js @@ -1,6 +1,6 @@ var Promise = require('bluebird'); -const ReviewsOptions = [ +var ReviewsOptions = [ '“Very stylish, great stay, great staff”', '“good hotel awful meals”', '“Need more attention to little things”', @@ -25,10 +25,10 @@ module.exports = { }); } - hotels.sort((a, b) => a.priceStarting - b.priceStarting); + hotels.sort(function (a, b) { return a.priceStarting - b.priceStarting; }); // complete promise with a timer to simulate async response - setTimeout(() => resolve(hotels), 1000); + setTimeout(function () { resolve(hotels); }, 1000); }); }, @@ -46,7 +46,7 @@ module.exports = { } // complete promise with a timer to simulate async response - setTimeout(() => resolve(reviews), 1000); + setTimeout(function () { resolve(reviews); }, 1000); }); } }; \ No newline at end of file diff --git a/Node/intelligence-SimilarProducts/README.md b/Node/intelligence-SimilarProducts/README.md index 012ab10d68..135c99c0c9 100644 --- a/Node/intelligence-SimilarProducts/README.md +++ b/Node/intelligence-SimilarProducts/README.md @@ -29,8 +29,8 @@ if (hasImageAttachment(session)) { var stream = getImageStreamFromMessage(session.message); imageService .getSimilarProductsFromStream(stream) - .then(visuallySimilarProducts => handleApiResponse(session, visuallySimilarProducts)) - .catch(error => handleErrorResponse(session, error)); + .then(function (visuallySimilarProducts) { handleApiResponse(session, visuallySimilarProducts); }) + .catch(function (error) { handleErrorResponse(session, error); }); } ```` @@ -42,10 +42,10 @@ And here is the implementation of `imageService.getSimilarProductsFromStream(str * @param {stream} stream The stream to an image. * @return {Promise} Promise with visuallySimilarProducts array if succeeded, error otherwise */ -exports.getSimilarProductsFromStream = stream => { +exports.getSimilarProductsFromStream = function (stream) { return new Promise( - (resolve, reject) => { - const requestData = { + function (resolve, reject) { + var requestData = { url: BING_API_URL, encoding: 'binary', formData: { @@ -56,7 +56,7 @@ exports.getSimilarProductsFromStream = stream => { } }; - request.post(requestData, (error, response, body) => { + request.post(requestData, function (error, response, body) { if (error) { reject(error); } diff --git a/Node/intelligence-SimilarProducts/app.js b/Node/intelligence-SimilarProducts/app.js index 4f8764b070..a13dbf37e5 100644 --- a/Node/intelligence-SimilarProducts/app.js +++ b/Node/intelligence-SimilarProducts/app.js @@ -5,28 +5,28 @@ A Similar Products bot for the Microsoft Bot Framework. // This loads the environment variables from the .env file require('dotenv-extended').load(); -const builder = require('botbuilder'), - imageService = require('./image-service'), +var builder = require('botbuilder'), restify = require('restify'), request = require('request').defaults({ encoding: null }), url = require('url'), - validUrl = require('valid-url'); + validUrl = require('valid-url'), + imageService = require('./image-service'); // Maximum number of hero cards to be returned in the carousel. If this number is greater than 10, skype throws an exception. -const MAX_CARD_COUNT = 10; +var MAX_CARD_COUNT = 10; //========================================================= // Bot Setup //========================================================= // Setup Restify Server -const server = restify.createServer(); -server.listen(process.env.port || process.env.PORT || 3978, () => { +var server = restify.createServer(); +server.listen(process.env.port || process.env.PORT || 3978, function () { console.log('%s listening to %s', server.name, server.url); }); // Create chat bot -const connector = new builder.ChatConnector({ +var connector = new builder.ChatConnector({ appId: process.env.MICROSOFT_APP_ID, appPassword: process.env.MICROSOFT_APP_PASSWORD }); @@ -34,20 +34,20 @@ const connector = new builder.ChatConnector({ server.post('/api/messages', connector.listen()); // Gets the similar images by checking the type of the image (stream vs URL) and calling the appropriate image service method. -const bot = new builder.UniversalBot(connector, function (session) { +var bot = new builder.UniversalBot(connector, function (session) { if (hasImageAttachment(session)) { var stream = getImageStreamFromMessage(session.message); imageService .getSimilarProductsFromStream(stream) - .then(visuallySimilarProducts => handleApiResponse(session, visuallySimilarProducts)) - .catch(error => handleErrorResponse(session, error)); + .then(function (visuallySimilarProducts) { handleApiResponse(session, visuallySimilarProducts); }) + .catch(function (error) { handleErrorResponse(session, error); }); } else { var imageUrl = parseAnchorTag(session.message.text) || (validUrl.isUri(session.message.text) ? session.message.text : null); if (imageUrl) { imageService .getSimilarProductsFromUrl(imageUrl) - .then(visuallySimilarProducts => handleApiResponse(session, visuallySimilarProducts)) - .catch(error => handleErrorResponse(session, error)); + .then(function (visuallySimilarProducts) { handleApiResponse(session, visuallySimilarProducts); }) + .catch(function (error) { handleErrorResponse(session, error); }); } else { session.send('Did you upload an image? I\'m more of a visual person. Try sending me an image or an image URL'); } @@ -59,11 +59,11 @@ const bot = new builder.UniversalBot(connector, function (session) { //========================================================= //Sends greeting message when the bot is first added to a conversation -bot.on('conversationUpdate', message => { +bot.on('conversationUpdate', function (message) { if (message.membersAdded) { - message.membersAdded.forEach(identity => { + message.membersAdded.forEach(function (identity) { if (identity.id === message.address.bot.id) { - const reply = new builder.Message() + var reply = new builder.Message() .address(message.address) .text('Hi! I am SimilarProducts Bot. I can find you similar products. Try sending me an image or an image URL.'); bot.send(reply); @@ -76,18 +76,19 @@ bot.on('conversationUpdate', message => { // Utilities //========================================================= -const hasImageAttachment = session => { +function hasImageAttachment(session) { return session.message.attachments.length > 0 && session.message.attachments[0].contentType.indexOf('image') !== -1; -}; -const getImageStreamFromMessage = message => { +} + +function getImageStreamFromMessage(message) { var headers = {}; var attachment = message.attachments[0]; if (checkRequiresToken(message)) { // The Skype attachment URLs are secured by JwtToken, // you should set the JwtToken of your bot as the authorization header for the GET request your bot initiates to fetch the image. // https://github.com/Microsoft/BotBuilder/issues/662 - connector.getAccessToken((error, token) => { + connector.getAccessToken(function (error, token) { var tok = token; headers['Authorization'] = 'Bearer ' + token; headers['Content-Type'] = 'application/octet-stream'; @@ -98,33 +99,32 @@ const getImageStreamFromMessage = message => { headers['Content-Type'] = attachment.contentType; return request.get({ url: attachment.contentUrl, headers: headers }); -}; +} function checkRequiresToken(message) { return message.source === 'skype' || message.source === 'msteams'; } - /** * Gets the href value in an anchor element. * Skype transforms raw urls to html. Here we extract the href value from the url * @param {string} input Anchor Tag * @return {string} Url matched or null */ -const parseAnchorTag = input => { +function parseAnchorTag(input) { var match = input.match("^[^<]*$"); if (match && match[1]) { return match[1]; } return null; -}; +} //========================================================= // Response Handling //========================================================= -const handleApiResponse = (session, images) => { +function handleApiResponse(session, images) { if (images && images.constructor === Array && images.length > 0) { var productCount = Math.min(MAX_CARD_COUNT, images.length); @@ -143,9 +143,9 @@ const handleApiResponse = (session, images) => { } else { session.send('Couldn\'t find similar products images for this one'); } -}; +} -const constructCard = (session, image) => { +function constructCard(session, image) { return new builder.HeroCard(session) .title(image.name) .subtitle(image.hostPageDisplayUrl) @@ -156,9 +156,9 @@ const constructCard = (session, image) => { builder.CardAction.openUrl(session, image.hostPageUrl, 'Buy from merchant'), builder.CardAction.openUrl(session, image.webSearchUrl, 'Find more in Bing') ]); -}; +} -const handleErrorResponse = (session, error) => { +function handleErrorResponse(session, error) { session.send('Oops! Something went wrong. Try again later.'); console.error(error); -}; +} diff --git a/Node/intelligence-SimilarProducts/image-service.js b/Node/intelligence-SimilarProducts/image-service.js index 442978c9b2..c677f44ae8 100644 --- a/Node/intelligence-SimilarProducts/image-service.js +++ b/Node/intelligence-SimilarProducts/image-service.js @@ -1,21 +1,21 @@ // The exported functions in this module makes a call to Bing Image Search API returns similar products description if found. // Note: you can do more functionalities like recognizing entities. For more info checkout the API reference: // https://msdn.microsoft.com/en-us/library/dn760791.aspx -const request = require('request').defaults({ encoding: null }); +var request = require('request').defaults({ encoding: null }); -const BING_API_URL = 'https://api.cognitive.microsoft.com/bing/v5.0/images/search?modulesRequested=SimilarProducts&mkt=en-us&form=BCSPRD'; +var BING_API_URL = 'https://api.cognitive.microsoft.com/bing/v5.0/images/search?modulesRequested=SimilarProducts&mkt=en-us&form=BCSPRD'; -const BING_SEARCH_API_KEY = process.env.BING_SEARCH_API_KEY; +var BING_SEARCH_API_KEY = process.env.BING_SEARCH_API_KEY; /** * Gets the similar products of the image from an image stream * @param {stream} stream The stream to an image. * @return {Promise} Promise with visuallySimilarProducts array if succeeded, error otherwise */ -exports.getSimilarProductsFromStream = stream => { +exports.getSimilarProductsFromStream = function (stream) { return new Promise( - (resolve, reject) => { - const requestData = { + function (resolve, reject) { + var requestData = { url: BING_API_URL, encoding: 'binary', formData: { @@ -26,7 +26,7 @@ exports.getSimilarProductsFromStream = stream => { } }; - request.post(requestData, (error, response, body) => { + request.post(requestData, function (error, response, body) { if (error) { reject(error); } @@ -46,10 +46,10 @@ exports.getSimilarProductsFromStream = stream => { * @param {string} url The URL to an image. * @return {Promise} Promise with visuallySimilarProducts array if succeeded, error otherwise */ -exports.getSimilarProductsFromUrl = url => { +exports.getSimilarProductsFromUrl = function (url) { return new Promise( - (resolve, reject) => { - const requestData = { + function (resolve, reject) { + var requestData = { url: BING_API_URL + '&imgurl=' + url, headers: { 'Ocp-Apim-Subscription-Key': BING_SEARCH_API_KEY @@ -57,7 +57,7 @@ exports.getSimilarProductsFromUrl = url => { json: true }; - request.get(requestData, (error, response, body) => { + request.get(requestData, function (error, response, body) { if (error) { reject(error); } diff --git a/Node/intelligence-SpeechToText/README.md b/Node/intelligence-SpeechToText/README.md index cfb31871dd..c11133ad77 100644 --- a/Node/intelligence-SpeechToText/README.md +++ b/Node/intelligence-SpeechToText/README.md @@ -32,10 +32,10 @@ In this sample we are using the API to get the text and send it back to the user if (hasAudioAttachment(session)) { var stream = getAudioStreamFromMessage(session.message); speechService.getTextFromAudioStream(stream) - .then(text => { + .then(function (text) { session.send(processText(text)); }) - .catch(error => { + .catch(function (error) { session.send('Oops! Something went wrong. Try again later.'); console.error(error); }); @@ -45,12 +45,12 @@ if (hasAudioAttachment(session)) { And here is the implementation of `speechService.getTextFromAudioStream(stream)` in [speech-service.js](speech-service.js) ````JavaScript -exports.getTextFromAudioStream = (stream) => { +exports.getTextFromAudioStream = function (stream) { return new Promise( - (resolve, reject) => { + function (resolve, reject) { if (!speechApiAccessToken) { try { - authenticate(() => { + authenticate(function () { streamToText(stream, resolve, reject); }); } catch (exception) { diff --git a/Node/intelligence-SpeechToText/app.js b/Node/intelligence-SpeechToText/app.js index afa43fd9b2..cac5e0365a 100644 --- a/Node/intelligence-SpeechToText/app.js +++ b/Node/intelligence-SpeechToText/app.js @@ -5,40 +5,40 @@ A speech to text bot for the Microsoft Bot Framework. // This loads the environment variables from the .env file require('dotenv-extended').load(); -const builder = require('botbuilder'), +var builder = require('botbuilder'), fs = require('fs'), needle = require('needle'), restify = require('restify'), request = require('request'), - speechService = require('./speech-service.js'), - url = require('url'); + url = require('url'), + speechService = require('./speech-service.js'); //========================================================= // Bot Setup //========================================================= // Setup Restify Server -const server = restify.createServer(); -server.listen(process.env.port || process.env.PORT || 3978, () => { +var server = restify.createServer(); +server.listen(process.env.port || process.env.PORT || 3978, function () { console.log('%s listening to %s', server.name, server.url); }); // Create chat bot -const connector = new builder.ChatConnector({ +var connector = new builder.ChatConnector({ appId: process.env.MICROSOFT_APP_ID, appPassword: process.env.MICROSOFT_APP_PASSWORD }); server.post('/api/messages', connector.listen()); -const bot = new builder.UniversalBot(connector, function (session) { +var bot = new builder.UniversalBot(connector, function (session) { if (hasAudioAttachment(session)) { var stream = getAudioStreamFromMessage(session.message); speechService.getTextFromAudioStream(stream) - .then(text => { + .then(function (text) { session.send(processText(text)); }) - .catch(error => { + .catch(function (error) { session.send('Oops! Something went wrong. Try again later.'); console.error(error); }); @@ -50,20 +50,20 @@ const bot = new builder.UniversalBot(connector, function (session) { //========================================================= // Utilities //========================================================= -const hasAudioAttachment = session => { +function hasAudioAttachment(session) { return session.message.attachments.length > 0 && (session.message.attachments[0].contentType === 'audio/wav' || session.message.attachments[0].contentType === 'application/octet-stream'); -}; +} -const getAudioStreamFromMessage = message => { +function getAudioStreamFromMessage(message) { var headers = {}; var attachment = message.attachments[0]; if (checkRequiresToken(message)) { // The Skype attachment URLs are secured by JwtToken, // you should set the JwtToken of your bot as the authorization header for the GET request your bot initiates to fetch the image. // https://github.com/Microsoft/BotBuilder/issues/662 - connector.getAccessToken((error, token) => { + connector.getAccessToken(function (error, token) { var tok = token; headers['Authorization'] = 'Bearer ' + token; headers['Content-Type'] = 'application/octet-stream'; @@ -74,47 +74,46 @@ const getAudioStreamFromMessage = message => { headers['Content-Type'] = attachment.contentType; return needle.get(attachment.contentUrl, { headers: headers }); -}; +} function checkRequiresToken(message) { return message.source === 'skype' || message.source === 'msteams'; } -const processText = (text) => { +function processText(text) { var result = 'You said: ' + text + '.'; if (text && text.length > 0) { - const wordCount = text.split(' ').filter(x => x).length; + var wordCount = text.split(' ').filter(function (x) { return x; }).length; result += '\n\nWord Count: ' + wordCount; - const characterCount = text.replace(/ /g, '').length; + var characterCount = text.replace(/ /g, '').length; result += '\n\nCharacter Count: ' + characterCount; - const spaceCount = text.split(' ').length - 1; + var spaceCount = text.split(' ').length - 1; result += '\n\nSpace Count: ' + spaceCount; - const m = text.match(/[aeiou]/gi); - const vowelCount = m === null ? 0 : m.length; + var m = text.match(/[aeiou]/gi); + var vowelCount = m === null ? 0 : m.length; result += '\n\nVowel Count: ' + vowelCount; } return result; -}; +} //========================================================= // Bots Events //========================================================= // Sends greeting message when the bot is first added to a conversation -bot.on('conversationUpdate', message => { +bot.on('conversationUpdate', function (message) { if (message.membersAdded) { - message.membersAdded.forEach(identity => { + message.membersAdded.forEach(function (identity) { if (identity.id === message.address.bot.id) { - const reply = new builder.Message() + var reply = new builder.Message() .address(message.address) .text('Hi! I am SpeechToText Bot. I can understand the content of any audio and convert it to text. Try sending me a wav file.'); bot.send(reply); - return; } }); } diff --git a/Node/intelligence-SpeechToText/speech-service.js b/Node/intelligence-SpeechToText/speech-service.js index d20edb5f63..f964460a96 100644 --- a/Node/intelligence-SpeechToText/speech-service.js +++ b/Node/intelligence-SpeechToText/speech-service.js @@ -1,20 +1,19 @@ - -const uuid = require('node-uuid'), +var uuid = require('node-uuid'), request = require('request'); -const SPEECH_API_KEY = process.env.MICROSOFT_SPEECH_API_KEY; +var SPEECH_API_KEY = process.env.MICROSOFT_SPEECH_API_KEY; // The token has an expiry time of 10 minutes https://www.microsoft.com/cognitive-services/en-us/Speech-api/documentation/API-Reference-REST/BingVoiceRecognition -const TOKEN_EXPIRY_IN_SECONDS = 600; +var TOKEN_EXPIRY_IN_SECONDS = 600; var speechApiAccessToken = ''; -exports.getTextFromAudioStream = (stream) => { +exports.getTextFromAudioStream = function (stream) { return new Promise( - (resolve, reject) => { + function (resolve, reject) { if (!speechApiAccessToken) { try { - authenticate(() => { + authenticate(function () { streamToText(stream, resolve, reject); }); } catch (exception) { @@ -27,8 +26,8 @@ exports.getTextFromAudioStream = (stream) => { ); }; -const authenticate = (callback) => { - const requestData = { +function authenticate(callback) { + var requestData = { url: 'https://api.cognitive.microsoft.com/sts/v1.0/issueToken', headers: { 'content-type': 'application/x-www-form-urlencoded', @@ -36,7 +35,7 @@ const authenticate = (callback) => { } }; - request.post(requestData, (error, response, token) => { + request.post(requestData, function (error, response, token) { if (error) { console.error(error); } else if (response.statusCode !== 200) { @@ -51,10 +50,10 @@ const authenticate = (callback) => { } } }); -}; +} -const streamToText = (stream, resolve, reject) => { - const speechApiUrl = [ +function streamToText(stream, resolve, reject) { + var speechApiUrl = [ 'https://speech.platform.bing.com/recognize?scenarios=smd', 'appid=D4D52672-91D7-4C74-8AD8-42B1D98141A5', 'locale=en-US', @@ -66,7 +65,7 @@ const streamToText = (stream, resolve, reject) => { 'requestid=' + uuid.v4() ].join('&'); - const speechRequestData = { + var speechRequestData = { url: speechApiUrl, headers: { 'Authorization': speechApiAccessToken, @@ -74,7 +73,7 @@ const streamToText = (stream, resolve, reject) => { } }; - stream.pipe(request.post(speechRequestData, (error, response, body) => { + stream.pipe(request.post(speechRequestData, function (error, response, body) { if (error) { reject(error); } else if (response.statusCode !== 200) { @@ -83,4 +82,4 @@ const streamToText = (stream, resolve, reject) => { resolve(JSON.parse(body).header.name); } })); -}; \ No newline at end of file +} \ No newline at end of file