Stan Wiechers Stan Wiechers - 1 year ago 100
Node.js Question

Asynchronous Botframework Response possible?

Most node.js botframework examples involve the notion of the waterfall dialog model, which is a great way to structure conversations, but we don't need that since we have our own chat system. We simply receive messages via the webhook, process them and respond without the dialog system.

Also, and now we are getting to the heart of the matter;), the examples I have seen communicate back to the botframework in the web context:

var connector = new builder.ChatConnector({config});
var bot = new builder.UniversalBot(connector);
server.post('/api/messages', connector.listen());
bot.dialog('/', (session, args) => {
session.sendTyping();
session.send( 'Echo'+ session.message.text);
})


The above example simply responds with an 'echo' and before that set's the typing status.
Our system works asynchronous, the way we currently work is by bypassing the connector listen and dialog scheme. A simplified example of how we queue a botframework message.

server.post('/api/messages/:name', (req, res, next)=>{
queue.post('botframework',req.params.name,req.body)
.then(()=>res.sendStatus(200))
});


In the queue processing, we construct the botframework objects:

//the ':name' from the snippet above is used to identify
//the bot a retrieve credentials
const connector = new botbuilder.ChatConnector({
appId: bot.properties.botframework_id.value.appId,
appPassword: bot.properties.botframework_id.value.appPassword
});
const username=message.from.name.replace(/[\s-;:"';$]/g,"_")+"_skype";

var address = {
"channelId": message.channelId,
"user": message.from,
"bot": message.recipient,
"serviceUrl": message.serviceUrl,
"useAuth": true
};
let bot = new botbuilder.UniversalBot(connector);
let msg = new botbuilder.Message();

//processing...
//create the outgoing message...

bot.send(msg);


The problem here for us is that we simply don't know how to create a session object from a raw webhook message which is needed for the typing indicator and to ensure the order of messages when many messages are sent in quick succession.

Here is what we wish to accomplish:

//the ':name' from the snippet above is used to identify
//the bot a retrieve credentials
//the context is non HHTP
const connector = new botbuilder.ChatConnector({
appId: bot.properties.botframework_id.value.appId,
appPassword: bot.properties.botframework_id.value.appPassword
});
const username=message.from.name.replace(/[\s-;:"';$]/g,"_")+"_skype";

var address = {
"channelId": message.channelId,
"user": message.from,
"bot": message.recipient,
"serviceUrl": message.serviceUrl,
"useAuth": true
};
let bot = new botbuilder.UniversalBot(connector);
let session = bot.createSession();

session.sendTyping();

let message = getNextMessageFromChatServer(message);
session.send(message);
//more messages to be send?
//....


So the question: How can we create a session object from the raw data send to the botframework webhook?

Answer Source

You should be able to build a session using loadSession

var address = {
    "channelId": message.channelId,
    "user": message.from,
    "bot": message.recipient,
    "serviceUrl": message.serviceUrl,
    "useAuth": true 
};
let bot = new botbuilder.UniversalBot(connector);
let msg = new botbuilder.Message();

bot.loadSession(address, (err, session) => {
  session.send("Message");
})
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download