Integrating Microsoft Bot Framework with api.ai - heroku

I am working on integrating Microsoft Bot Framework with api.ai. I followed the tutorials here. On coding, I also deployed the bot to Heroku using Heroku command line.
I have used the code as below:
(I have changed my APP ID and Password):
var builder = require('botbuilder');
var restify = require('restify');
var apiairecognizer = require('api-ai-recognizer');
var request = require('request');
//=========================================================
// Bot Setup
//=========================================================
// Setup Restify Server
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
var connector = new builder.ChatConnector({
appId: '4c8f3u2b-c56n-4117-bc16-ec31eeb5d25c',
appPassword: '4CBNO8vBGtdcGh9PoiVYottY'
});
var connector = new builder.ConsoleConnector().listen();
var bot = new builder.UniversalBot(connector);
var recognizer = new apiairecognizer("84c78b2c15684c7380c6a74c8fbb343f");
var intents = new builder.IntentDialog({
recognizers: [recognizer]
});
bot.dialog('/',intents);
intents.matches('Flow_1',function(session, args){
var fulfillment = builder.EntityRecognizer.findEntity(args.entities, 'fulfillment');
if (fulfillment){
var speech = fulfillment.entity;
session.send(speech);
}else{
session.send('Sorry...not sure how to respond to that');
}
});
intents.onDefault(function(session){
session.send("Sorry...can you please rephrase?");
});`
My Package.json
{
"name": "nodebot",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"api-ai-recognizer": "^1.0.1",
"botbuilder": "^3.8.4",
"restify": "^4.3.0"
}
}
My Procfile
web: node app.js
But after successfully deploying to Heroku, I am seeing the following error:
{"code":"ResourceNotFound","message":"/api/messages does not exist"}
Even when I tried testing the bot from Bot Framework Emulator, I am seeing the below error:
Request to 'http://localhost:3978/api/messages' failed: [404] Not Found
I have following questions:
1. How to successfully integrate api.ai with Framework?
2. How to host it Heroku?

It seems that the api/messages route is not defined. You are missing this line server.post('/api/messages', connector.listen());.
Also, you are defining the connector twice, the ChatConnector and the ConsoleConnector. Make sure to delete the code related to the ConsoleConnector.

Related

handleMessageError when registering Teams connector

I'm developing a Microsoft Teams custom app that can add connectors to Teams channels.
My connector has been working fine for a few months now, but a few weeks ago, the ability to register new connectors has stopped working:
After clicking “Save” on the connector configuration page, “loading” shows up until it times out (see the console screenshot below).
When I look in the browser console, I see that the outbound request was actually successful and notifySuccess() was called on the save event, but Teams does not register it (see full JS code below).
Also, a handleMessageError message is emitted, but I could not figure out what the issue is.
I tried this in the native app and in Chrome, and a client tried it in another instance of Teams as well.
Is this a bug or a (undocumented?) change in the Teams API?
Console / UI screenshot
JSON Error Message:
{
"seq": 1615787354693,
"timestamp": 1615793440583,
"flightSettings": {
"Name": "ConnectorFrontEndSettings",
"AriaSDKToken": "d127f72a3abd41c9b9dd94faca947689-d58285e6-3a68-4cab-a458-37b9d9761d35-7033",
"SPAEnabled": true,
"ClassificationFilterEnabled": true,
"ClientRoutingEnabled": true,
"EnableYammerGroupOption": true,
"EnableFadeMessage": false,
"EnableDomainBasedOwaConnectorList": false,
"EnableDomainBasedTeamsConnectorList": false,
"DevPortalSPAEnabled": true,
"ShowHomeNavigationButtonOnConfigurationPage": false,
"DisableConnectToO365InlineDeleteFeedbackPage": true
},
"status": 500,
"clientType": "SkypeSpaces",
"connectorType": "fc0ee140-b62a-4947-9af1-d19a66a00af8",
"name": "handleMessageError"
}
JS code that runs on the connector's configuration page:
const XHR = new XMLHttpRequest();
const subscriptionApiUrl = "https://XYZ.execute-api.us-east-1.amazonaws.com/Prod/subscriptions/";
const channelsApiBaseURL = "https://www.example.com/api/library/v2/channels/";
const defaultChannelParameters = "sorting=latest&language=en&excludeReviews=true";
const url = new URL(window.location.href);
const clientId = url.searchParams.get("clientid");
const clientSecret = url.searchParams.get("clientsecret");
const teamsSettings = {
entityId: "Example",
contentUrl: "https://www.example.com/xyz",
configName: "Example"
};
var saveEvent;
console.log("Example Connector initializing");
microsoftTeams.initialize();
microsoftTeams.settings.setValidityState(true); // make Save button enabled
microsoftTeams.settings.registerOnSaveHandler(handleSaveEvent);
function handleSaveEvent(e) {
saveEvent = e;
microsoftTeams.settings.setSettings(teamsSettings);
microsoftTeams.settings.getSettings(storeSettings);
}
function storeSettings(settings) {
XHR.addEventListener("load", reportSuccess);
XHR.addEventListener("error", reportFailure);
XHR.open("POST", subscriptionApiUrl);
XHR.setRequestHeader("Content-Type", "application/json");
XHR.send(composePayload(settings.webhookUrl));
console.log("Request to store Example Connector sent");
}
function composePayload(webhookUrl) {
return JSON.stringify({
webhookUrl: webhookUrl,
gaChannelUrl: channelsApiBaseURL + document.getElementById("ga-channel-id").value + "/items?" + defaultChannelParameters,
gaClientId: clientId,
gaClientSecret: clientSecret,
cronSchedule: "0 " + document.getElementById("time").value + " * * " + document.getElementById("frequency"),
postNow: document.getElementById("post-now").checked ? true : false
});
}
function reportSuccess(e) {
console.log("Example Connector registered!");
saveEvent.notifySuccess();
}
function reportFailure(e) {
let msg = "Could not connect to subscription API.";
console.log(msg);
saveEvent.notifyFailure(msg);
}
I got the same error. I registered the connector and downloaded the generated manifest.json then packaged (with icons) and tried to sideload the zip. I got the same error when trying to "Save".
I then tried to edit the generated manifest using the App Studio (App Studio -> Import an existing app) and this time I got a meaningful error saying the property needsIdentity is not valid according the schema from the manifest (https://developer.microsoft.com/en-us/json-schemas/teams/v1.3/MicrosoftTeams.schema.json)
Removing this property fixed the issue and I was able to save the connector configuration.
I could not find any documentation about this property. I checked the last version of the schema by now (1.8) and it's not there !!
I created an issue : https://github.com/MicrosoftDocs/msteams-docs/issues/2949

FCM push notification with parse server

I need to add FCM push in parse server setting. Please help me.
However when sending from parse. There is some issue between parse server and FCM then.
Here is my index.js, sample code:
var express = require("express");
var ParseServer = require("/usr/lib/node_modules/parse-server").ParseServer;
var ParseDashboard = require("/usr/lib/node_modules/parse-dashboard");
var allowInsecureHTTP = true;
var api = new ParseServer({
databaseURI: "mongodb://127.0.0.1:27017/****",
appId: "****",
masterKey: "****",
serverURL: "http://**.**.**.**:1234/parse",
push: {
ios: {
pfx: "/usr/lib/node_modules/push_crt.p12",
passphrase: "example",
bundleId: "com.example",
production: true
},
android: {
senderId: "123456",
apiKey: "******"
}
}
});
var dashboard = new ParseDashboard(
{
apps: [
{
serverURL: "http://**.**.**.**:1234/parse",
appId: "******",
masterKey: "******",
appName: "MyApp"
}
],
users: [{ user: "admin", pass: "admin" }]
},
allowInsecureHTTP
);
var app = express();
// make the Parse Server available at /parse
app.use("/parse", api);
// make the Parse Dashboard available at /dashboard
app.use("/dashboard", dashboard);
var httpServer = require("http").createServer(app);
httpServer.listen(1234);
Please check and help me. How to add FCM connection inside parse server.
For the ios configuration, I can see 2 errors:
pfx path is probably wrong and that wont work on a server cause its not relative (ie. thats specific to your local computer). Save the file in a "certs" (or whatever you wanna call it) folder where you got the nodejs code. Then update with pfx: __dirname + '/certs/push_crt.p12'
bundleId is not the right key, this should be updated to topic: 'com.example'
For the android config, im not sure what senderId is for, maybe you should get rid of that, unless you are sure you need it.

bot framework not receiving Slack dialog.open form response

I am building bot with Bot Builder SDK for Node.js
The bot is for slack
I have configured the slack and botframework correctly, as per the doc Connect a bot to Slack
All communication between botframework, slack and node service is through HTTPS.
The framework is communicating with slack properly.
In Next step, I am working on slack dialog.open
First of all, I could not find any method in Bot Builder SDK, to open the slack dialog, I even tried to Implement channel-specific functionality
Finally I was able to open dialog with direct post to: https://slack.com/api/dialog.open
But when I submit the form, I am getting error:
We had some trouble connecting. Try again?
Please see the screenshot:
The console displays the following error:
Request URL: https://xxxxx.slack.com/api/dialog.submit
Response: {"ok":false,"error":"curl_error"}
Slack send payload with "type":"dialog_submission".
I have tested that by changing the "Interactive Components -> Request URL", to my bot service.
To make slack communicate directly to my bot service.
Reference: section "Add and Configure Interactive Messages (optional)" in Connect a bot to Slack
So, I am sure message is being sent from the dialog box, when I click on submit button.
The message is lost between slack and my bot service. when Request URL is set to: https://slack.botframework.com/api/Actions
I never receives any indication that service is receiving a message.
Please help me to resolve this problem.
Following is the code that I used to open the dialog:
let RESTClient = require('node-rest-client').Client;
let FrameworkClient = new RESTClient();
let Promise = require('bluebird');
openDialogBox: function(token, trigger_id, callback_id) {
return new Promise(function(resolve, reject) {
var dialog = {
"title": "Issue Details",
"submit_label": "Submit",
"callback_id": callback_id,
"elements": [
{
"type": "text",
"label": "Pickup Location",
"name": "loc_origin"
},
{
"type": "text",
"label": "Dropoff Location",
"name": "loc_destination"
}
]
};
var args = {};
args.headers = {Authorization: 'Bearer ' + token, 'Content-type': 'application/json; charset=utf-8'};
args.data = {"trigger_id": trigger_id, "dialog": dialog};
FrameworkClient.post("https://slack.com/api/dialog.open", args , function(data, response) {
if (data && data.ok) {
resolve(data);
} else {
reject();
}
});
});
}
Thanks
As per #JasonSowers (Engineer - Microsoft Bot Framework)
Microsoft Bot Framework do not support this right now.
They may support this in future.

Amazon Alexa custom skill issue in ios app

I'm trying to implement custom skills using Amazon Alexa Skill Kit (ASK). I have configured Amazon Alexa Voice Service (AVS) and ASK project, Then created lambda function also.
I have 2 custom intents.
{
"intents": [
{
"intent": "fIntent"
},
{
"intent": "bIntent"
},
{
"intent": "AMAZON.HelpIntent"
},
{
"intent": "AMAZON.StopIntent"
}
]
}
I have a Utterances like below
fIntent get info
fIntent get status
fIntent find info
fIntent info
Here is my index.js code
'use strict';
var Alexa = require('alexa-sdk');
var SKILL_NAME = 'ScottSkill';
var APP_ID = '';
exports.handler = function(event, context, callback) {
var alexa = Alexa.handler(event, context);
alexa.registerHandlers(handlers);
alexa.execute();
};
var handlers = {
'LaunchRequest': function () {
this.emit(':tellWithCard','Hi, Im your personal car assistant. How can i help you');
},
'fIntent':function (){
this.emit(':tell','Fuel level is 100');
},
'AMAZON.HelpIntent': function () {
var readFuel = 'Iam Personal car assistant, I can assist you with car info';
var speeachOutput = readFuel;
var reprompt = 'How can I help you';
this.emit(':ask', speeachOutput, reprompt);
},
'AMAZON.StopIntent': function () {
this.emit(':tell', 'OKay, Goodbye');
},
'AMAZON.CancelIntent': function () {
this.emit(':tell', 'OKay, Goodbye');
}
};
Now the problem is when I'm saying skill name I'm getting LaunchRequest message.
But when I'm trying to get custom intent value by saying fIntent info
I'm not getting the message what I configured in the index.js file.
if I say info its should tell Fuel level is 100.
But I'm Not getting that info. Can someone help me?
Don't develop the two components at one.
First develop you skill and test it from an Echo device
Once you are done, develop your Amazon Voice Service app

MS BotBuilder : How can the bot receive parameters and initiate conversation at webchat start

I'm using the direct-line method to communicate with this bot :
var connector = new builder.ChatConnector({
appId: process.env.MICROSOFT_APP_ID || config.appId,
appPassword: process.env.MICROSOFT_APP_PASSWORD || config.appPassword
});
// Initialize bot
var bot = universalBot(connector);
var server = restify.createServer();
server.listen(process.env.port || port, function () {
console.log('%s listening to %s', server.name, server.url);
});
var botListener = connector.listen();
server.post('/api/messages', (req, resp) => {
token = req.query.token;
console.log(token); //prints the token to the terminal
botListener(req, resp);
});
var msg = new builder.Message()
.text(notification);
//.address(address)
bot.send(msg, function (err) {
// Return success/failure
res.status(err ? 500 : 200);
res.end();
});
In order to pro-actively send the message i still need the address of the user and conversation id.
Is there a way to obtain these information at the time this initialisation on the browser ;
var bot = {
id: params['botid'] || 'botid',
name: params['botname'] || 'botname',
screen: params['screen'] || null
};
BotChat.App({
directLine: {
//secret: params['s'],
token: params['t'],
//domain: params['domain'],
//webSocket: params['webSocket']
},
user: user, //Need to access this user object at server on the webchat start
bot: bot
}, document.getElementById("BotChatGoesHere"));
Or any other way where the bot can start the conversation when the user loads the html in the browser.
UPDATE : The conversationUpdate dialog serves for triggering and initiating a dialog, but how can I access the parameter (token) and user object sent along, inside conversationUpdate dialog?
Thanks
If I understand you correctly, you want your bot to prompt the user with something like Hi, what can I help you with today? the minute the webchat loads, right? I haven't tried the direct line, always used the provided iframe, and here's what I do in my bot to send the welcome message:
bot.on('conversationUpdate', (message) => {
(message.membersAdded || [])
.filter((identity) => identity.id == message.address.bot.id)
.forEach((identity) => {
const reply = new builder.Message()
.address(message.address)
.text("Hi, How can I help you today?");
bot.send(reply);
});
});
I believe what you are looking for is the backchannel. With this, you can send values to your bot. the backchannel documentation is at the bottom of the readme on that repo.

Resources