Microsoft Bot Framework with Azure Functions App and NodeJS - node.js

I am trying to build a bot using Microsoft Bot Framework. I am planning to use a Azure Function with Http Trigger as the endpoint. NodeJS is the language of my choice. I am seeing botframework examples with restify and nodejs but none on using azure functions. Can anyone point me to an example where botframework is developed using azure functions and nodejs or give me an example on how to do it.

From Chris Anderson...
https://github.com/christopheranderson/functions-bot-example
You'll need to connect it to an HTTP trigger and the following code does the integration.
var listen = bot.listen();
var response = function (context) {
return {
send: function (status, message) {
var _msg = message ? message : (typeof status !== 'number' ? status : null)
var _status = typeof status === 'number' ? status : 200
var res = {
status: _status,
body: _msg
};
context.res = res;
context.done();
}
}
}
module.exports = function (context, req) {
listen(req, response(context))
}

You can see here https://github.com/vjrantal/bot-sample/commit/e80faefded1c9da9a8b0d69e36497bb221b54709 a changeset that brings Azure Functions compatibility to a bot built with restify.
The approach is borrowed from Chris Anderson's project at https://github.com/christopheranderson/functions-bot-example but includes updates to work with the latest botbuilder.
UPDATE: On latest Functions runtime, you don't need the wrapping anymore. See https://github.com/vjrantal/bot-sample/commit/fe56a16f6f0286bfe66095eefc417388c1bc1e1c for details.

Related

How to access individual request param coming from GCP pubsub as a input to the cloud function node js?

I am writing a cloud function in node js, My requirement is that GCP pubsub topic will publish a json body as a message. This pubsub topic is a trigger point to my node js cloud function. It means whenever I publish a message from topic It should trigger my cloud function. This functionality is working as expected. But the issue comes where I am trying to access individual element of Json request data in my cloud function. If I log the data which is coming from pubsub in my cloud function, I am able to do that.
My index.js
exports.helloPubSub = (data, context) => {
const pubSubMessage = data;
const messageData = pubSubMessage.data
? Buffer.from(pubSubMessage.data, 'base64').toString()
: 'World';
console.log(`message data is, ${messageData}!`);
};
Published pubsub message is :
{
"companyName": "my-company",
"companyLocation": "my-location"
}
When I am trying to access "companyName" in my cloud function from above published message I get log output as "company name is undefined". Below is the code I am trying:
exports.helloPubSub = (data, context) => {
const pubSubMessage = data;
const messageData = pubSubMessage.data
? Buffer.from(pubSubMessage.data, 'base64').toString()
: 'World';
console.log(`company name is, ${messageData.companyName}!`);
};
Note: I am referring https://cloud.google.com/functions/docs/tutorials/pubsub
Your helpful answers will be appreciated. Thank you !
You can't access the companyName because you try to access a property from a string.
To access the data sent from PubSub you need to parse the decoded string using JSON.
Try the following code:
exports.helloPubSub = (event, context) => {
const message = Buffer.from(event.data, 'base64').toString();
const messageData = JSON.parse(message)
console.log(`company name is, ${messageData.companyName}!`);
};

Unable to stream microphone audio to Google Speech to Text with NodeJS

I am going to develop a simple web based Speech to Text project. Develop with NodeJS, ws (WebSocket), and Google's Speech to Text API.
However, I have no luck to get the transcript from Google's Speech to Text API.
Below are my server side codes (server.js):
ws.on('message', function (message) {
if (typeof message === 'string') {
if(message == "connected") {
console.log(`Web browser connected postback.`);
}
}
else {
if (recognizeStream !== null) {
const buffer = new Int16Array(message, 0, Math.floor(message.byteLength / 2));
recognizeStream.write(buffer);
}
}
});
Below are my client side codes (ws.js):
function recorderProcess(e) {
var floatSamples = e.inputBuffer.getChannelData(0);
const ConversionFactor = 2 ** (16 - 1) - 1;
var floatSamples16 = Int16Array.from(floatSamples.map(n => n * ConversionFactor));
ws.send(floatSamples16);
}
function successCallback(stream) {
window.stream = stream;
var audioContext = window.AudioContext;
var context = new audioContext();
var audioInput = context.createMediaStreamSource(stream);
var recorder = context.createScriptProcessor(2048, 1, 1);
recorder.onaudioprocess = recorderProcess;
audioInput.connect(recorder);
recorder.connect(context.destination);
}
When I run the project, and open http://localhost/ in my browser, trying to speaking some sentences to the microphone. Unfortunately, there are no transcription returned, and no error messages returned in NodeJS console.
When I check the status in Google Cloud Console, it only display a 499 code in the dashboard.
Many thanks for helping!
I think the issue could be related to the stream process. Maybe some streaming process is stopped before the end of an operation. My suggestion is to review the callbacks in the JasvaScript code in order to find some “broken" promises.
Also, maybe its obvious but there is a different doc for audios than more than a minute:
https://cloud.google.com/speech-to-text/docs/async-recognize
CANCELLED - The operation was cancelled, typically by the caller.
HTTP Mapping: 499 Client Closed Request
Since the error message, this also could be related to the asynchronous and multithread features of node js.
Hope this works!

Welcome message Bot Framework v4 nodejs

I'm developing a multichannel bot (focusing on web and telegram) that's based on Microsoft's Bot Framework (https://learn.microsoft.com/en-us/azure/bot-service/?view=azure-bot-service-4.0)
I'm stuck with the initial message the user is getting.
My bot is based on the complex bot published by Microsoft: https://github.com/Microsoft/BotFramework-Samples/tree/master/SDKV4-Samples/js/complexDialogBot
Issue I'm seeing is that in the emulator bot is working great, on the web user is not greeted with the welcome message. I've used iframe to integrate the bot.
I'm checking activity types and when members are added to the chat, but seems like it's not triggering on the web.
if (turnContext.activity.type === ActivityTypes.ConversationUpdate) {
if (turnContext.activity.membersAdded && turnContext.activity.membersAdded.length > 0) {
await this.sendWelcomeMessage(turnContext);
}
}
I saw similar questions asked but either for bot framework v3 or C# implementation (like this one Welcome message not visibile in Webchat,but work in Emulator and Welcome Message not working in Azure portal using Microsoft Bot Builder SDK(v4) for nodejs)
try using this
enter code here
this.onMembersAdded(async context => {
const membersAdded = context.activity.membersAdded;
for (let cnt = 0; cnt < membersAdded.length; cnt++) {
if (membersAdded[cnt].id == context.activity.recipient.id) {
const welcomeCard = CardFactory.adaptiveCard(WelcomeCard);
}
}
});
You can solve your problem in below code
in iframe to integrate the bot you can write member Adding code copy in inside !turnContext.responded
if (turnContext.activity.type === ActivityTypes.Message) {
if (!turnContext.responded) {
await this.sendWelcomeMessage(turnContext);
}
}

Trigger a specific dialog in Bot via Directline API

I'm working on breaking my bot repo into 2 separate repos
A repo to purely handle bot logic
A repo to handle custom chat via directline
Currently , we have a feature where we can trigger the bot to start a specific dialog if its mentioned as a parameter in the URL. So something like
https://foo.com/?param=bar
would trigger the bar dialog
This is the code that handles it
function(userId, conversationId, params, token){
return new Promise((resolve, reject)=>{
var _directlineAddress = {
bot: {"id":config.BOT.ID, "name": config.BOT.HANDLE},
channelId: "directline",
serviceUrl: config.BOT.DIRECTLINE_URL,
useAuth: true,
user:{"id": userId},
"conversation": {"id": conversationId}
}
if(params.options){
var _re = /^\?(\w+)*=(\w+)*/
var _programType = _re.exec(params.options);
if (_programType[1] === "foo") {
var _dialogId = "*:/foo";
}
else {
var _dialogId = "*:/" + _programType[1];
}
} else {
var _dialogId = "*:/";
var _specialParams = {"sessionId":token};
}
bot.beginDialog(_directlineAddress, _dialogId, _specialParams, function(err){
else{
resolve();
}
});
})
};
Since i'm splitting the directline from the bot logic , i will no longer be having access to the bot object. therefore bot.beginDialog would not work here
Is there a way i can trigger the dialog by posting to the Directline API?
No. With Direct Line you will be able to send messages to the bot. I guess that a way to go here will be to define a convention message that you will send via Direct Line and that the bot logic will know that it will have to start a dialog based on it.

Windows Azure node.js Push notification for Windows store 8.1 - How to use 'createRawTemplateRegistration' template?

Please explain with one example as I am getting Error: 400 - The specified resource description is invalid.
Basically, I want to update badge value. But there is no template for badge registration in WnsService API document (http://azure.github.io/azure-sdk-for-node/azure-sb/latest/WnsService.html). So, I am trying with "createRawTemplateRegistration" template to update the badge value.
Please help me on this.
You can directly use the function sendBadge() to push badge value to client devices.
Please try the following code:
var azure = require('azure');
var notificationHubService = azure.createNotificationHubService('<hubname>', '<connectionstring>');
notificationHubService.wns.sendBadge(null,99,function(error,response){
if(error) console.log(error);
console.log(response);
})
Any further concern, please feel free to let me know.
update
Do you mean that you want only one template and to handle all the types of notifications including Raw, Toast, Badge? If so, I think the answer is negative. According the description http://azure.github.io/azure-sdk-for-node/azure-sb/latest/WnsService.html#createRawTemplateRegistration:
Remember that you have to specify the X-WNS-Type header
So the header option is required. And according the REST API which is invoked via this api in nodejs is Create Registration, and we can find the description:
The BodyTemplate element is mandatory, as is the X-WNS-Type header.
So we should specify the notification type for the template.
update1
This code sample works fine on my side:
var channel = '<devicetoken>';
var templateMessage = { text1: '$(message)' };
notificationHubService.wns.createRawTemplateRegistration(channel,'tag',JSON.stringify(templateMessage), {headers: { 'X-WNS-Type': 'wns/raw' }},
function (e, r) {
if (e) {
console.log(e);
} else {
console.log({
id: r.RegistrationId,
deviceToken: r.DeviceToken,
expires: r.ExpirationTime
});
}
}
)

Resources