Rasa, Botfront and heroku: Frontend doesn't work after deployment - python

I have deployed my rasa chatbot online by creating a docker image, pushing and releasing it to Heroku. Now my bot is live on Heroku. I would like to communicate with this bot, through my website. I have added my bot url to Botfront widget's socketurl. However, when I send a message, I do not get any response. Does anyone know what I'm missing or doing wrong?
The content of my script is:
<!-- chatbot -->
<script>
!(function () {
let e = document.createElement("script"),
t = document.head || document.getElementsByTagName("head")[0];
(e.src = "{% static 'js/chatbot.js' %}"),
(e.async = !0),
(e.onload = () => {
window.WebChat.default(
{
customData: { language: "en" },
socketUrl: "https://app-name.herokuapp.com",//not real bot url
// add other props here
// initPayload: "/greet",
title: "Let's talk, we are online.",
subtitle: "Say hi to get started.",
},
null
);
}),
t.insertBefore(e, t.firstChild);
})();
</script>
If someone can help me, I would really appreciate it, been stuck on this for days!

Did you add the SocketIO configuration? You should add the following in your credentials.yml file (it will be inside your Docket container, not in git repository).
socketio:
user_message_evt: user_uttered
bot_message_evt: bot_uttered
session_persistence: true # or false
You can see more details in RASA documentation for web channel.

I see, since Heroku is using python as server end it might be not able to load index.html or any HTML code. try hosting your HTML code to a different server. I would suggest using Github's profile hosting.
I have also hosted my HTML page on GitHub and rasa server on a cloud server.
check it out here: https://horizon733.github.io/
Also, check out this documentation by Heroku while using the python server.
I hope this helps, feel free to ask any doubts.

Related

Sending message from Flask to JS via socketio

I'm trying to wrap my head around this socketio thing and have hit a wall regarding sending a message from my Flask backend to my JavaScript frontend. My app is a consolidated control panel for my church's PTZ camera and OBS Studio. Here are the logical steps I'm trying to implement:
Connect Flask to OBS via the OBS websocket.
Receive notification in Flask when the Graphics source visibility in OBS changes.
Send a message from Flask to my JS frontend to let it know that the Graphics source has changed visibility (making a two-way sync with the button on my control panel and the actual source in OBS).
Steps 1 and 2 are working, but I can't get the 3rd one to work.
Here is my Python where I use the message from OBS to call the function to sync with the JS frontend. (I know the sync_graphics_toggle runs, but the JS never gets the emit message.)
def on_visibility_change(message):
if (message.getItemName() == "Graphics"):
sync_graphics_toggle(message.getItemVisible())
def sync_graphics_toggle(obs_graphics_visible):
socketio.emit('syncGraphicsToggle', obs_graphics_visible, namespace='/main')
In the JavaScript (with just a console log to test):
$(document).ready(function() {
const socketMain = io("/main");
socketMain.on("connect", function() {
console.log("Made connection in graphics-preview", socketMain.id);
});
socketMain.on("syncGraphicsToggle", function(obsGraphicsVisible) {
console.log("Got syncGraphicsToggle command")
});
}
I have verified that I'm connected, but I don't get the message from Flask.
I have other implementations of socketio in my code that work fine, but those are initiated by actions on the webpage. So, I'm thinking there is something I don't understand about sending messages that are initiated by the server.
Any pointers would be greatly appreciated.
John
Windows 10
Python = 3.10.4
Flask = 2.2.2
Python Socket.IO = 5.7.2
JS Socket.IO = 4.5.3

chatbot interrupts conversation

I’m creating a chatbot a bit different from what we are used to use and I need help and advice. The idea is that the chatbot has an external interface as I have read that for the bot to start the conversation is necessary (correct me if it is not true), the problem is that I have never created an interface like this and when I have tried to take created projects and test them to see how it would look like I can not get it to work, I attach an example of how it looks once written rasa.
Example of a conversation:
(11:22) User:Hello
(11:22) Bot: Hello, how can I help you?
(11:23) User: What will the weather be like today?
(11:23) Bot: It will rain this afternoon.
(Stands by on hold)
(14:12) Bot: It's already raining.
(14:13) User: Will it rain for a long time?
(14:13) Bot: Yes, it will be raining for about three hours
I know how to do the first part, until the bot takes the initiative, but I don't know how to continue.
index.html:
<html>
<body>
<script>!(function () {
let e = document.createElement("script"),
t = document.head || document.getElementsByTagName("head")[0];
(e.src =
"https://cdn.jsdelivr.net/npm/rasa-webchat#1.0.0/lib/index.js"),
// Replace 1.x.x with the version that you want
(e.async = !0),
(e.onload = () => {
window.WebChat.default(
{
initPayload: '/greet',
customData: { language: "en" },
socketUrl: "http://localhost:5005",
// add other props here
},
null
);
}),
t.insertBefore(e, t.firstChild);
})();
</script>
</body>
</html>
credentials.yml:
# This file contains the credentials for the voice & chat platforms
# which your bot is using.
# https://rasa.com/docs/rasa/messaging-and-voice-channels
rest:
# # you don't need to provide anything here - this channel doesn't
# # require any credentials
#facebook:
# verify: "<verify>"
# secret: "<your secret>"
# page-access-token: "<your page access token>"
#slack:
# slack_token: "<your slack token>"
# slack_channel: "<the slack channel>"
# slack_signing_secret: "<your slack signing secret>"
socketio:
user_message_evt: user_uttered
bot_message_evt: bot_uttered
session_persistence: true
#mattermost:
# url: "https://<mattermost instance>/api/v4"
# token: "<bot token>"
# webhook_url: "<callback URL>"
# This entry is needed if you are using Rasa X. The entry represents credentials
# for the Rasa X "channel", i.e. Talk to your bot and Share with guest testers.
rasa:
url: "http://localhost:5002/api"
I have several questions:
Why if I type rasa shell the chatbot works correctly but if I type rasa run -m models --enable-api --cors "*" --debug and open index.html I get a blank.
[enter image description here][1]
How to make the second part even to test it with rasa shell?
Can you start the bot in different ways, for example, It is starting to rain and other times: It has stopped snowing?
Any ideas, suggestions, pages that can help me?
Thank you!
[1]: https://i.stack.imgur.com/shcz0.png
Why if I type rasa shell the chatbot works correctly but if I type
rasa run -m models --enable-api --cors "*" --debug and open index.html
I get a blank. enter image description here
I suggest using the official rasa chat widget as your frontend. If you have questions about it you can ask it in the rasa forum. If you found a bug, you can file a bug report in the rasa open source repo.
How to make the second part even to test it with rasa shell?
This documentation on how to get the bot to start the conversation with the user should help you get started.
Can you start the bot in different ways, for example, It is starting
to rain and other times: It has stopped snowing?
You can send to the bot the trigger intent that will trigger the desired response from the bot. See answer to the question for details.

How to get node web client to talk to REST API on Heroku?

I have a node web client called bidsell, and a small Python Tornado REST API called quote. Bidsell when triggered makes regular http get calls to quote. Quote duely returns random price information as json. Works locally - want to share it online, but how? Heroku looks promising. Have tried already to deploy both bidsell and quote in the same project on heroku, each running within their own heroku web dyno or deployment container. From the logs "heroku log" both are installed correctly but only one appears to be running. So I can access the front page url of bidsell, for example, but when bidsell is triggered to go fetch quote info the quote service is not found :-( Should I be using another deployment pattern?
ok so as jr0cket suggested I created 2 heroku projects - one for the bidsell node project and one for the quote service.
In addition to the bidsell node project source files I had a procfile containing the following:
web: npm start
and a scripts section in package.json informing heroku how to start the app:
"scripts": {
"start": "gulp serve"
}
In addition to the quoteService source python file I had a procfile containing the following:
web: python quoteService.py
and a requirements.txt file containing:
tornado==3.1.1
pyrestful==0.4.1
Had the following proxy.js as middleware in the bidsell app:
'use strict';
var proxyMiddleware = require('http-proxy-middleware');
var options = {
target: 'http://quoteservce.herokuapp.com:80',
changeOrigin: true
};
var proxy = proxyMiddleware('/quote', options);
module.exports = function(){
return [proxy];
}
being called from server.js:
'use strict';
..
var middleware = require('./proxy');
module.exports = function(options) {
function browserSyncInit(baseDir, browser) {
browser = browser === undefined ? 'default' : browser;
..
var server = {
baseDir: baseDir,
routes: routes
};
server.middleware = middleware();
browserSync.instance = browserSync.init({
port: (process.env.PORT || 5000),
startPath: '/',
server: server,
browser: browser
});
}
..
gulp.task('serve', ['watch'], function () {
browserSyncInit([options.tmp + '/serve', options.src]);
});
..
};
to allow communication between bidsell and quoteService. For further background info take a look here
The running app you can find here.
May take a little while for the idle free-tier heroku dynos to fire up ;-)
Bidsell project on git.
QuoteService project on git.
As your project is two seperate technology stacks, the easiest approach is to deploy these as two separate Heroku apps. This gives you simple way to create the specific environment (languages, runtimes, libraries) needed for each app / service.
You could create an Heroku configuration variable QUOTE_REST_API for the node web client that points to the external web address. For example, using the heroku toolbelt
heroku config:set QUOTE_REST_API=https://quote-api.herokuapp.com/
Using the QUOTE_REST_API configuration variable in your node client would give a simple way to change the address of the quote without having to change your code.
If you are running two separate projects in one Heroku app, you need to ensure that you have two web: entries for the Procfile to start your separate processes. Only processes marked as web will listen to web traffic.
You may not be able to run two different web processes if you use the free tier of heroku.

How to convert terminal window chat application (built using socket programming, written in python) into a web application?

So, I wrote this chat application which works well in terminal windows:
GitHub Source
Now what I want is to convert into a web chat application so that my friends can connect/chat/test it from their network. But, I am clueless about how to proceed!
Please help me. Suggest me which technologies can I use to make it available on a website?
It looks like you've written a Python server to handle your Python chat clients, and you'd like to extend this to web clients.
I would recommend using a real-time network such as PubNub to relay data between your chat clients and the server. Using a real-time network means that you can spend less time worrying about low-level socket issues such as concurrency and more time building your application.
In the case of PubNub, a Python SDK will allow your server to subscribe to chat channels, while the JavaScript SDK will help with web-based clients. You can build a simple JavaScript-based web client using the code in this blog post: Build Real-Time Chat Apps in 10 Lines of Code.
Enter Chat and press enter
<div><input id=input placeholder=you-chat-here /></div>
Chat Output
<div id=box></div>
<script src=http://cdn.pubnub.com/pubnub.min.js></script>
<script>(function(){
var box = PUBNUB.$('box'), input = PUBNUB.$('input'), channel = 'chat';
PUBNUB.subscribe({
channel : channel,
callback : function(text) { box.innerHTML = (''+text).replace( /[<>]/g, '' ) + '<br>' + box.innerHTML }
});
PUBNUB.bind( 'keyup', input, function(e) {
(e.keyCode || e.charCode) === 13 && PUBNUB.publish({
channel : channel, message : input.value, x : (input.value='')
})
} )
})()</script>
Then, on your Python server, you could subscribe to the same chat channel:
# Listen for Messages *BLOCKING*
def receive(message) :
broadcast_data(message) #This is using your Python function from your github link
return True
pubnub.subscribe({
'channel' : 'chat',
'callback' : receive
})
Let me know if this works for you. Good luck!

Specify URLS for CORS in Django app on Heroku

I have an app in Heroku running with Django.
Now I'm starting to develop a Phonegap app that I want to make work with my Heroku app.
I can't make it work because of CORS (Cross-origin resource sharing) protection. So I need to exclude some urls (not all app) to make my Phonegap app work.
I've tried installing django-cors-headers, but it doesn't seem to work.
To test it, I'm making a call to obtain a csrf_token.
I added this to my setting.py (and of course followed the guide, setting all to default):
CORS_URLS_REGEX = r'^register/.*$'
CORS_URLS_REGEX = r'^login/.*$'
CORS_URLS_REGEX = r'^getcsrf/.*$'
And this is the Ajax call I try to make:
get: function() {
$.getJSON("http://domain.herokuapp.com/getcsrf/",
{
tags: "jquery,javascript",
tagmode: "any",
format: "json"
},
function(data) {
$.each(data.items, function(item){
console.log(item);
});
});
}
But I get this marked in red as an error and an empty response field:
GET http://domain.herokuapp.com/getcsrf/?tags=jquery%2Cjavascript&tagmode=any&format=json 200 OK 206ms
There's no cross origin restrictions with phonegap, it's using a webview, not a web browser.
The only thing you have to do with phonegap/cordova is to be sure your server is whitelisted in config.xml.
In cordova 3.3/3.4, the default setting is <access origin="*" /> which should allow access to any url.

Categories

Resources