I added bot to an HTML page on our intranet using the following code:
<link href="https://cdn.botframework.com/botframework-webchat/latest/botchat.css" rel="stylesheet" />
<style>
#bot{
height: 600px;
}
</style>
<div>
<div id="bot" />
</div>
<script src="https://cdn.botframework.com/botframework-webchat/latest/botchat.js"></script>
<script>
var user = {
id: 'user-id',
name: 'user name'
};
var botConnection = new BotChat.DirectLine({
token: '[token]',
user: user
});
BotChat.App({
user: user,
botConnection: botConnection,
bot: { id: 'test', name: 'test' }
}, document.getElementById("bot"));
botConnection
.postActivity({
from: user,
name: 'WelcomeDialog',
type: 'event',
value: ''
})
.subscribe(function (id) {
console.log('"trigger requestWelcomeDialog" sent');
});
</script>
Now, I need to send data back to this client, to be executed on that HTML page, since the page exists within the context of our intranet (internal servers), so I want to have the intent return from LUIS and directed to specific dialog, then send the required entity value from this dialog to the client to be executed there, then send the result back to the server so I can display a formatted message to the user.
So basically, I would need to have 2-way communication between the client (added to my intranet) and the bot itself (the nodejs app hosted in azure)
Update:
I implemented the backchannel in my bot, so now the code looks like this:
jQuery(function () {
//get user name from the system
var userid = _spPageContextInfo.userId;
var requestUri = _spPageContextInfo.webAbsoluteUrl + "/_api/web/getuserbyid(" + userid + ")";
var requestHeaders = { "accept": "application/json;odata=verbose" };
$.ajax({
url: requestUri,
contentType: "application/json;odata=verbose",
headers: requestHeaders,
success: onSuccess,
error: onError
});
function onSuccess(data, request) {
var loginName = data.d.Title;
var user = {
id: userid,
name: loginName
};
var botConnection = new BotChat.DirectLine({
token: '[token]',
user: user
});
let FindPerson = function (personName) {
let msg = `You asked for ${personName}`
botConnection
.postActivity({ type: "event", value: msg, from: { id: "me" }, name: "FindPersonResultFound" })
.subscribe(id => console.log("success"));
}
BotChat.App({
user: user,
botConnection: botConnection,
bot: { id: 'TestBot', name: 'test bot' }
}, document.getElementById("bot"));
botConnection
.postActivity({
from: user,
name: 'WelcomeDialog',
type: 'event',
value: ''
})
.subscribe(function (id) {
console.log('"trigger requestWelcomeDialog" sent');
});
botConnection.activity$
.filter(activity => activity.type === "event" && activity.name === "FindPerson")
.subscribe(activity => FindPerson(activity.value))
}
function onError(error) {
alert("error");
}
})
My server side code looks like this:
bot.on('event', function (message) {
if (message.name == 'WelcomeDialog') {
bot.beginDialog(message.address, message.name);
}
if (message.name === "FindPersonResultFound") {
bot.beginDialog(message.address, message.name, message.value)
}
});
However, if I send a message that's related to any dialog, it gets repeated as if the sender is me:
According to your output, I assumpt that your bot application would contain a default root dialog / which will return any thing you input.
If so, you can try to change beginDialog to replaceDialog in your bot event register functions, to clear the previous dialog stack.
Also, you could provide more code about your bot application, so that we can have a deeper looking over.
Related
I got this code from my client iOS app on XCode console
Firebase registration token: diWY78iar8s:APA91bHJAzXe384OEYvfk4bKsyS1NQvteph7DwG7JRIMm_HuXg8EeNllVrsSi0v9W_Gh95ezbOStp3ZWuWl0AzFKxMaCOjN81yiz7A5qhkONrd7lP2CTkUbFErw28r3ONTLvo8c8sO7h
diWY78iar8s:APA91bHJAzXe384OEYvfk4bKsyS1NQvteph7DwG7JRIMm_HuXg8EeNllVrsSi0v9W_Gh95ezbOStp3ZWuWl0AzFKxMaCOjN81yiz7A5qhkONrd7lP2CTkUbFErw28r3ONTLvo8c8sO7h
NodeJS
console.log("START");
var FCM = require('fcm-node');
var serverKey = require('/Users/bheng/Desktop/Apps/APNS/node/mhn-app-firebase-adminsdk-bs45c-5ac3770488.json')
var fcm = new FCM(serverKey)
var collapseKey = 'new_message';
var message = {
to: 'diWY78iar8s:APA91bHJAzXe384OEYvfk4bKsyS1NQvteph7DwG7JRIMm_HuXg8EeNllVrsSi0v9W_Gh95ezbOStp3ZWuWl0AzFKxMaCOjN81yiz7A5qhkONrd7lP2CTkUbFErw28r3ONTLvo8c8sO7hdiWY78iar8s:APA91bHJAzXe384OEYvfk4bKsyS1NQvteph7DwG7JRIMm_HuXg8EeNllVrsSi0v9W_Gh95ezbOStp3ZWuWl0AzFKxMaCOjN81yiz7A5qhkONrd7lP2CTkUbFErw28r3ONTLvo8c8sO7h',
data: {
cpeMac: '000000000000',
type: 'malware'
},
notification: {
title: 'Hello baby',
body: 'Nice body',
tag: collapseKey,
icon: 'ic_notification',
color: '#18d821',
sound: 'default',
},
};
fcm.send(message, function(err, response){
if (err) {
console.log("Something has gone wrong!")
console.log(JSON.stringify(err));
} else {
console.log("Successfully sent with response: ", JSON.stringify(response))
}
})
console.log("END");
Result
When I run it
node app.js
I kept getting
START
END
Successfully sent with response: {"results":[{"error":{"code":"messaging/invalid-registration-token","message":"Invalid registration token provided. Make sure it matches the registration token the client app receives from registering with FCM."}}],"canonicalRegistrationTokenCount":0,"failureCount":1,"successCount":0,"multicastId":7577724855311354000}
How would one go about debugging this further?
your token has some additional random string such as
to: 'diWY78iar8s:APA91bHJAzXe384OEYvfk4bKsyS1NQvteph7DwG7JRIMm_HuXg8EeNllVrsSi0v9W_Gh95ezbOStp3ZWuWl0AzFKxMaCOjN81yiz7A5qhkONrd7lP2CTkUbFErw28r3ONTLvo8c8sO7hdiWY78iar8s:APA91bHJAzXe384OEYvfk4bKsyS1NQvteph7DwG7JRIMm_HuXg8EeNllVrsSi0v9W_Gh95ezbOStp3ZWuWl0AzFKxMaCOjN81yiz7A5qhkONrd7lP2CTkUbFErw28r3ONTLvo8c8sO7h',
just remove : diWY78iar8s: from your token string
console.log("START");
var FCM = require('fcm-node');
var serverKey = require('/Users/bheng/Desktop/Apps/APNS/node/mhn-app-firebase-adminsdk-bs45c-5ac3770488.json')
var fcm = new FCM(serverKey)
var collapseKey = 'new_message';
var message = {
to: 'APA91bHJAzXe384OEYvfk4bKsyS1NQvteph7DwG7JRIMm_HuXg8EeNllVrsSi0v9W_Gh95ezbOStp3ZWuWl0AzFKxMaCOjN81yiz7A5qhkONrd7lP2CTkUbFErw28r3ONTLvo8c8sO7hdiWY78iar8s:APA91bHJAzXe384OEYvfk4bKsyS1NQvteph7DwG7JRIMm_HuXg8EeNllVrsSi0v9W_Gh95ezbOStp3ZWuWl0AzFKxMaCOjN81yiz7A5qhkONrd7lP2CTkUbFErw28r3ONTLvo8c8sO7h',
data: {
cpeMac: '000000000000',
type: 'malware'
},
notification: {
title: 'Hello baby',
body: 'Nice body',
tag: collapseKey,
icon: 'ic_notification',
color: '#18d821',
sound: 'default',
},
};
fcm.send(message, function(err, response){
if (err) {
console.log("Something has gone wrong!")
console.log(JSON.stringify(err));
} else {
console.log("Successfully sent with response: ", JSON.stringify(response))
}
})
console.log("END");
Response from FCM :
Successfully sent with response: { results: [ { messageId: '0:1543448946734425%479ec0e2479ec0e2' } ],
canonicalRegistrationTokenCount: 0,
failureCount: 0,
successCount: 1,
multicastId: 6133765431734591000 }
One of the interesting reasons for invalid registration is: that device have a different token. Maybe you are trying to use a past token.
In my case what happened was I was getting the FCMRegistrationToken from my colleague via Discord and the Ctrl+C Ctrl+V was modifying the token. On obtaining the token via email solved the issue.
I am using socket io chat for making interface between user and admin. I have include socket library in my view code and implemented it on user dashboard.Now currently i am getting conversation between all users and admin in user individual chat box. While sending message from user to admin it working fine only conversation between that user and admin is with in one chat room in admin panel. How can i get chat between individual user and admin in user dashboard.
view code:
<script>
var localuserid = '<%-user.id%>';
var socket = io()
socket.on("chat", addChat)
$(() => {
getChats()
$("#send").click((e) => {
e.preventDefault();
var chatMessage = {
chat: $('#btn-chat-input').val(),
userid: $('#userid').val(),
role: 'user',
sender: $('#userid').val(),
msg_desc: $('#btn-chat-input').val(),
reciever: $('#adminid').val()
}
//console.log(chat);
postChat(chatMessage);
addChat(chatMessage);
$('#btn-chat-input').val();
});
})
function postChat(chat) {
$.post("/saveuserchat", chat)
}
function getChats() {
$.get("/getuserchat", (chats) => {
//console.log(chats);
chats.forEach(addChat)
})
}
function addChat(chatObj) {
$("#chat_message").append(`<p class="usermsg">${chatObj.msg_desc}</p>`);
}
$.ajax({
type: "GET",
url: "/getuserchat?senderid="+localuserid,
success: function(data){
console.log(data);
}
})
</script>
controller code:
app.get('/getuserchat',isLoggedIn,function(req, res) {
// var senderId = req.param("senderid");
chat.find({}, function(error, chats){
console.log(chats);
res.send(chats);
});
});
I want to be able to trigger my bot who's on my SharePoint online Site by Droping a local file to him.
I created a WebPart to use this bot on the site, and putting the embed code give by Azure.
But when i drop a file in the bot, it open the document in a new tab showing me the content.
I would like to start the conversation while drop a file like this :
Start of bot conversation by putting a file
I'd imagine some solution by using a drop zone on the iframe which contain the bot, but it's not working.
I visit some site who can help but i don't really know how to implement this : Bot in WebChat, DirectLine API, Send Activity to the bot
This GitHub could also be usefull.
You'll need to handle the ondragover and ondrop events (cancelling the default behavior) and post the activity manually:
html:
<div id="bot" ondrop="drop_handler(event);" ondragover="dragover_handler(event);" />
Javascript:
const dl = new BotChat.DirectLine({
secret: 'YourDLSecret',
webSocket: false
});
BotChat.App({
botConnection: dl,
user: { id: 'userid' },
bot: { id: 'botid' },
resize: 'detect'
}, document.getElementById("bot"));
function dragover_handler(ev) {
console.log("dragOver");
ev.preventDefault();
}
function drop_handler(ev) {
console.log("Drop");
ev.preventDefault();
ev.stopPropagation();
var files = [];
for (var i = 0; i < ev.dataTransfer.items.length; i++) {
// If dropped items aren't files, reject them
if (ev.dataTransfer.items[i].kind === 'file') {
var file = ev.dataTransfer.items[i].getAsFile();
files.push({
contentType: file.type,
contentUrl: window.URL.createObjectURL(file),
name: file.name
});
}
}
dl.postActivity({
from: { id: 'userid' },
type: 'message',
attachments: files
})
.subscribe(function (id) {
console.log('files sent');
});
}
I have the following code which attempts to set the user's name during a chat session. E.g. if the user writes the message "Hi, my name is Bob", the bot will respond by greeting the user with his name, but only if the name was labeled as a "name" entity.
The issue is that the name is globally set for every user that is currently chatting with the bot and not for the current user only. The bot will, in other words, call every user currently chatting Bob in this case.
var intents = new builder.IntentDialog({ recognizers: [recognizer] })
// Check if the message user sent matches LUIS intent "greetingsWithName"
.matches('greetingsWithName', (session, args) => {
// Attempt to set content of LUIS entity "name" to variable "name"
name = builder.EntityRecognizer.findEntity(args.entities, 'navn');
// Check whether the name was successfully set or not
if (!name) {
session.send('Sorry, I didn't catch your name.')');
} else {
session.userData.userName = name.entity;
session.send('Hi, ' + session.userData.userName);
});
Later on I check in code whether the user has given his name to the bot or not during the session. If so, then say goodbye to the user with his name:
.matches('goodBye', (session) => {
if (!session.userData.userName) {
session.send('Good bye!');
} else {
session.send('Good bye, ' + session.userData.userName);
}
})
bot.dialog('/', intents);
Here is the HTML code from the file that initiates the web chat session:
<!DOCTYPE html>
<html>
<head>
<link href="https://cdn.botframework.com/botframework-webchat/latest/botchat.css" rel="stylesheet" />
</head>
<body>
<div id="bot"/>
<script src="https://cdn.botframework.com/botframework-webchat/latest/botchat.js"></script>
<script>
BotChat.App({
directLine: { secret: direct_line_secret },
user: { id: 'userid' },
bot: { id: 'botid' },
resize: 'detect'
}, document.getElementById("bot"));
</script>
</body>
</html>
You are storing the name of the user in userData, which is logical.
But in your tester, you set the same user id for every webchat user:
user: { id: 'userid' }
So every user will point to the same userData as the key is a combination of the channel name and the user id (activity.ChannelId, activity.From.Id in C#).
You can avoid this by generating unique identifiers for every webchat user, for example using https://www.npmjs.com/package/uuid-random
In that case, user: { id: uuid() }.
Moreover if you need to set a display name, add name: '...' to the definition of user: user: { id: uuid(), name: 'You' }.
I have created a Microsoft bot on-premise (i.e. Hosted bot in IIS and Used Offline Directline for emulation using node package offline-directline-gss).
I am able to chat with the service but the issue I am facing is, since 'ConversationUpdate' doesn't work in webchat, I am posting the activity of type 'conversationupdate', text 'conversationupdate' on page load, and in the bot solution's Post method, I wrote a condition to check if activity.text is equal to 'conversationupdate' and wrote code to send a welcome message. But this is not happening.
In the command prompt which runs index.js, I can see the activity getting posted but the bot solution is not returning anything (or) something.
This the html page code:
<!DOCTYPE html>
<html>
<head>
<meta name="WebPartPageExpansion" content="full" />
<link href="BotChat/botchat.css" rel="stylesheet" />
</head>
<body>
<div id="bot"/>
<script src="Masterfiles/js/jquery-1.11.0.min.js"></script>
<script src="BotChat/botchat.js"></script>
<script>
$(window).on('load', function () {
try
{
botWindowExpandAndCollapse();
}
catch(err)
{
console.log(err.message);
}
});
function botWindowExpandAndCollapse()
{
try
{
var directLine = new BotChat.DirectLine({
secret: params['s'],
user: user,
bot: bot,
token: params['t'],
domain: 'http://127.0.0.1:3000/directline',
webSocket: false // defaults to true
});
directLine
.postActivity({ type: "conversationupdate", from: user, user:user, text:"conversationupdate"})
.subscribe(id => alert("Conversation updated"));
$('#bot .wc-chatview-panel').css('height','50px');
$('#bot .wc-chatview-panel').addClass('IconView');
//Script to hide
$( "<span class='DPfigure need-help'>Need Help</span>" ).insertAfter( ".wc-chatview-panel" );
if ($(".wc-chatview-panel").hasClass("fullHeight"))
{
$(".need-help").hide();
$('#bot .wc-chatview-panel').css('right','17px');
}
else
{
$(".need-help").show();
$('#bot .wc-chatview-panel').css('right','105px');
}
$('.DPfigure').click(function(){
$('#bot .wc-chatview-panel').toggleClass('fullHeight');
$('#bot .wc-chatview-panel').toggleClass('IconView');
if ($(".wc-chatview-panel").hasClass("fullHeight"))
{
$(".need-help").hide();
$('#bot .wc-chatview-panel').css('right','17px');
}
else
{
$(".need-help").show();
$('#bot .wc-chatview-panel').css('right','105px');
}
});
}
catch(err)
{
console.log(err.message);
}
}
var params = BotChat.queryParams(location.search);
debugger;
var user = {
id: Math.random().toString(36).substring(7),
name: params["username"] || 'username'
};
var bot = {
id: params['botid'] || 'botid',
name: params["botname"] || 'botname'
};
window['botchatDebug'] = params['debug'] && params['debug'] === "true";
BotChat.App({
directLine: {
secret: params['s'],
token: params['t'],
domain: 'http://127.0.0.1:3000/directline',
webSocket: false // defaults to true
},
user: user,
bot: bot,
locale: params['locale'],
resize: 'detect'
// sendTyping: true, // defaults to false. set to true to send 'typing' activities to bot (and other users) when user is typing
}, document.getElementById("bot"));
</script>
</body>
</html>
This is the index.js code:
const url = require("url");
const directline = require("offline-directline-gss/dist/bridge");
const express = require("express");
const app = express();
const config = {
localDirectLine: {
hostUrl: "http://localhost",
port: "3000"
},
apbots:[
{
botId:"TestingBot",
botUrl:"http://localhost:3374/api/messages",
"msaAppId": "",
"msaPassword": ""
},
]
};
directline.initializeRoutes(app, config);
command prompt indicating post message is successful:
Can anyone please throw some light on what could be the reason for this. Thank You!