Flask-SocketIO: Sending messages back to client - javascript

I am currently trying to implement a Twitter Stream using Twitter's Streaming API and I am using Flask-SocketIO for use in Python. Now I am able to send an emit to trigger a function in Flask which calls the Twitter API based on some keyword, but I want the text from the stream back to the JavaScript front-end which hasn't been too successful. I am able to send, for instance, a message like "Hi" if I listen on 'message', but I've tried to send JSON back to no avail.
My Flask function for this is:
#socketio.on('my event')
def handle_my_custom_event(json):
print('received json: ' + str(json))
r = api.request('statuses/filter', json)
for item in r.get_iterator():
if 'text' in item:
print(item['text'])
json_data = {'data': item['text']}
send(json_data, json=True)
JSON in this case is {'track':'$AAPL'} so fetches each tweet about Apple as it happens. item['text'] is the string of the tweet text. I've tried using send, also tried using emit('my response',json_data) and listened for 'my response' but I'm not sure I'm doing all of this right.
My front-end script for this currently looks like this:
$(document).ready(function() {
var socket = io.connect('http://' + document.domain + ':' + location.port);
socket.on('connect', function() {
socket.emit('my event', {'track': '$'+data_prices[0]['symbol'].toString()}, function(data){
console.log(data);
if (data.error)
console.log('Something went wrong on the server');
if (data.ok)
console.log('Event was processed successfully');
});
});
});
but I receive no console logs, nothing.
What would I have to do to receive the json_data object in my front-end script and have it log to the console?
UPDATE: I've managed to get them coming in when I emit them to an event 'my response' but it only seems to log to the console when I shut down the server. Is there a way to keep this running as a stream to the console so I can use the data in the front-end?

I discovered that my problem was the listener for the response was not properly set up so I changed the Flask function to:
#socketio.on('my event')
def handle_my_custom_event(json):
print('received json: ' + str(json))
r = api.request('statuses/filter', {'track':'pizza'})
for item in r.get_iterator():
if 'text' in item:
print(item['text'])
json_data = {'data': item['text']}
emit('my response',json_data)
then in the front-end I had:
$(document).ready(function() {
var socket = io.connect('http://' + document.domain + ':' + location.port);
socket.on('connect', function() {
socket.emit('my event', {'track': '$'+data_prices[0]['symbol'].toString()}, function(data){
console.log(data);
});
});
socket.on('my response', function(data){
console.log(data);
});
});
The issue is that Flask is by default synchronous, and to have the messages come in as and when they happen, when creating the SocketIO app, asynchronous mode has to be explicitly defined:
socketio = SocketIO(app, async_mode="threading")

Related

How to do otp verification using 2 factor

I have taken free trail from 2 factor for sending sms as otp and needs to be verified again, I am able to send the sms and also console.log the status on node side, but the issue is I am not able to send the response to client weather otp is sent or not and how could I verify it
What I have done till now
let otp = Math.floor(100000 + Math.random() * 900000) // geterating otp
const no = req.body.cPhoneNo //phone no from UI
console.log(no)
var options = {
"method": "POST",
"hostname": "2factor.in",
"port": null,
"path": "/API/V1/{{api_key}}/ADDON_SERVICES/SEND/TSMS",
"headers": {}
};
var req = http.request(options, function(res) {
var chunks = [];
res.on("data", function(chunk) {
chunks.push(chunk);
});
res.on("end", function() {
var body = Buffer.concat(chunks);
let sendData = body.toString()
console.log(body.toString())
res.json({status:body.toString}) //here I am getting error as type error json is not a function
});
});
req.write(JSON.stringify({
From: 'something',
To: no,
TemplateName: 'some Name',
VAR1: 'var 1',
VAR2: otp
// SendAt: '{OptionScheduleTime}'
}));
req.end();
I have mentioned with comment Where I am trying to send status back to client if it is send or not, but it is not taking json as throwing error .json throws type error
**One more thing I found from there website is **
I have found two url end points one to send sms with some session Id and other to get otp entered from user and verify that These are two urls
To send Otp https://2factor.in/API/V1/{api_key}/SMS/{phone_number}/AUTOGEN
To receive Otp https://2factor.in/API/V1/{api_key}/SMS/VERIFY/{session_id}/{otp_input}
api_key= The key I have got from 2factor
phone_number = receivers no
My issue is How I can use this endpoints to send the sms and to do verification, from client end I am on button click I am sending req to server via axios but in backend I have been suffering to send the msg and verify the otp
You can check out this link
Anyone out here please guide me
I don't see res.json method in node's HTTP module. Express has res.json method. Instead you should use JSON.parse. Have a look at this example from documentation.

How to send and receive data in sockets.io

I am stuck on something in sockets.io I want to send something to the server.js and then resend some of the data back out to everyone else connected.
So I would like to send something like
I have
userid="1"
username="dave"
message="some message"
So I would send it like :
userid:userid,
username:username,
message:message
At the moment I am only sending one paramater, 'message' like so :-
function sendmessage() {
var new_message = document.getElementById("message").value;
socket.emit('new_message', new_message);
}
and for the sever :
socket.on('new_message', function (data) {
console.log(data);
});
So I get the message ok but how do I send and receive and read the the rest and then send some of the data back out to everyone. Sorry but this is doing my head in and all the tutorials are just for sending msg.
To send a message to every socket connected : doc
io.emit('some event', { for: 'everyone' });
To answer your question about how to send multiple parameter, one way of doing this is to send an object with multiple keys.
function sendmessage() {
socket.emit('new_message', { userid, username, message });
}
socket.on('new_message', function(data){
console.log(`${data.userid} - ${data.username} - ${data.message} `);
});

AWS Lambda Node.js HTTP GET Request never executed

I have the following intent. When intent is entered I want to perform a GET request to an external API. The intent is entered, however my http.get requested is not. If you look below I added a log statement within the request and it is never executed. Any ideas what the problem may be?
'BlogEntrySlugIntent': function () {
var url = 'http://jsonplaceholder.typicode.com/posts/1';
http.get( url, function( response ) {
console.log('In get request');
response.on( 'data', function( data ) {
var text = 'Data returned is: ' + data;
this.emit(':tell', 'hellloooo');
});
});
},

Response for FileUploader's uploadComplete-Event is undefined

I'm developing a SAPUI5 app and use the FileUploader control in my app to upload documents to a server. The uploading works and I also receive a response from the server (I can see this in the DevTools of Chrome).The problem is that the event-object inside the 'uploadComplete' event-handler always returns undefined for the response parameter.
Do you know why this is the case and how I can fix it?
Here is the initialization of the FileUploader:
var oFileUploader = new sap.ui.unified.FileUploader({
uploadUrl: "/fileupload",
name: "documentUploader",
uploadOnChange: false,
multiple: false,
width: "400px",
uploadComplete: this.onDocumentUploadComplete
});
And here is the 'uploadComplete' event-handler:
onDocumentUploadComplete: function(oEvent) {
var response = oEvent.getParameter("response");
console.log(response); // response = undefined
}
I still haven't figured out how to receive the server's response but I have found a workaround.After uploading the file I just send a request to the server and tell it to check whether the file exists.If it exists the server returns "true" and if it doesn't the server returns "false". Here's my code:
// eventhandler for the "uploadComplete"-event of the FileUploader-control
onDocumentUploadComplete: function(oEvent) {
var uploaderControl = oEvent.getSource();
var documentname = uploaderControl.getValue();
var fileURI = "/file/" + documentname + "?exists";
$.get(fileURI, function(data) {
if (data === "true") {
console.log("Successfully uploaded: " + documentname);
this.handleDocumentUploadSuccess(documentname);
} else {
console.log("Error when uploading document: " + documentname);
this.handleDocumentUploadError(documentname);
}
}.bind(this));
}
According to the documentation the parameter response is subject to some conditions.
Response message which comes from the server. On the server side this
response has to be put within the "body" tags of the response document
of the iFrame. It can consist of a return code and an optional
message. This does not work in cross-domain scenarios.
That means the response fom the server must be XML or HTML.

How to set cookie using JavaScript after fetching API request in GCM Service Worker?

I have successfully implemented GCM and ServiceWorkers to receive push-notification.
My problem
Whenever there is a SOS update, I am sending a HTTP request to gcm-http which then shows up a normal notification on Google Chrome but without any payload or data.
According to Google Developers Doc, chrome cannot receive payload/data, so one have to manually fetch the notification from the backend when push event is triggered.
So to fetch the data I am requesting an url on my backend (in django) to send me the notification data. But problem lies here how will I know which notification's data I have to send from my database/model?
Note:- I am not maintaining a different database table/model to determine notifications read by the client, since its an SOS update and read/unread is not required.
Workaround which is not working:-
I can set a cookie on client's browser and on backend can get next notification (below is the code)
class GetSOSNotification(View):
notif_id = 0
def get(self, request):
if 'last_notif_id' in request.COOKIES:
notif_id = request.COOKIES.get('last_notif_id') + 1
sos = SOSUpdate.objects.get(id=notif_id)
else:
sos = SOSUpdate.objects.order_by('-timestamp').filter()[0]
notif_id = sos.id
data = dict()
data['notification'] = dict()
if sos.get_condition_display() and sos.get_subject_display():
data['notification']['title'] = sos.polling_station.name + " " + sos.get_subject_display() + " " + sos.get_condition_display()
elif sos.get_condition_display():
data['notification']['title'] = sos.polling_station.name + " " + sos.get_condition_display()
elif sos.get_subject_display():
data['notification']['title'] = sos.polling_station.name + " " + sos.get_subject_display()
else:
data['notification']['title'] = sos.polling_station.name + " SOS Alert!"
if sos.message:
data['notification']['message'] = sos.message
else:
data['notification']['message'] = "Please click here to check the details."
data['notification']['notif_id'] = notif_id
return JsonResponse(data)
but, I have to return JSON response, and therefoe I can't set cookie from server-side, therefore I planned to use data['notification']['notif_id'] on client-side (i.e., Javascript) to set cookie.
My SW.js's snippet looks like :
self.addEventListener('push', function(event) {
console.log('Push message', event);
event.waitUntil(
fetch("//localhost/get_sos_notification/").then(function(response){
if(response.status!=200){
console.log('Looks like there was a problem. Status Code: ' + response.status);
throw new Error();
}
return response.json().then(function(data){
if(data.error || !data.notification){
console.error('The API returned an error.', data.error);
throw new Error();
}
var title = data.notification.title;
var message = data.notification.message;
var icon = '//localhost/static/main/images/push-notification.png';
var notificationTag = data.notification.tag;
return self.registration.showNotification(title, {
body: message,
icon: icon,
tag: notificationTag
});
});
}).catch(function(err){
console.log('Unable to retrieve data', err);
var title = 'SOS - Update';
var message = 'We were unable to get the information, please click here to know the real message.';
var icon = '//localhost/static/main/images/push-notification.png';
var notificationTag = 'notification-error';
return self.registration.showNotification(title, {
body: message,
icon: icon,
tag: notificationTag
});
})
);
});
But I am not able to do document.cookie = last_notif_id=data.notification.notif_id at the place where I am handling received notification data (if successfully received), because the JS script is giving error Unable to retrieve data ReferenceError: document is not defined at http://localhost/static/main/js/sw.js
Additional information: //localhost/get_sos_notification/ is a GET request, returns JSON, and is mapped to class GetSOSNotification(View)
I have googled and searched SO a lot, but haven't got any solution.
Thanks in advance.

Categories