Trigger javascript function from Django server - javascript

I am working on IPN's. Whenever I receive an IPN in this url: https://www.mywebsitename.com/notifications, I would like to run a simple JavaScript function that displays some html content.
I manage the IPN's from the server side, as follows:
#csrf_exempt
def notifications(request):
if request.method == "POST":
#some code
I would like to trigger my JS function inside that block of code, but I can't come up with any way of doing this. Also I don't really know wether what I am asking is really possible or not, maybe there is another approach that I can't figure out by myself.

This is 100% possible with Django using Websockets. It sounds like you are trying to build a notification system for the UI based on when you receive a request at one of your urls. Start by checking out Django Channels: https://channels.readthedocs.io/en/stable/
This is the best way to use Websockets with Django, which can help you implement notifications or other real-time features. The tutorial in the docs is great. To solve your task, you should:
Follow the tutorial and set up a WebSocket consumer in your Django app to handle notifications. This is what will allow a frontend user to establish a real-time connection with your application and receive messages from it.
Finish your notifications_view. After the request from the payment comes in, you will be dispatching a message to your websocket consumer for whichever user needs to recieve the message. It could end up looking something like this:
# assuming that the request gives you the username of the user to be notified,
# and you have a group configured in your consumer
def notification_view(request):
if request.method == "POST":
username = request.POST.get('username')
group_name = 'notifications{}'.format(username)
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)(
group_name,
{
'type': 'new_payment',
'text': {
'eventType': 'notification',
'name': 'New Payment',
'userMessage': 'You just got paid'
}
}
return(HttpResponse(status=200))
This would send a message over the user's socket when the request is received.
In your js, you will setup a listener for the socket. Then you can listen for the messages and do whatever you desire in the document with the data you recieve, such as show a user a message:
var endpoint = 'ws://' + '<yourhost>/notifications/username/;
var socket = new ReconnectingWebSocket(endpoint);
socket.onmessage = e => {
data = JSON.parse(e.data);
let msg = document.createElement('<p>');
msg.innerText = data['text']['userMessage']
}
Just follow the tutorial and that will certainly get you headed in the right direction!

Related

How to send user specific data using SSE

i am trying to create a social media page where in home page of every user they can see feeds,
feeds from friend's post. when ever my friend create a post i can see the same in my feeds in real time.
For that i am using SSE in python flask. everything working find but after adding few more users only i realise all the post are coming to all logged in people's feed. which wrong, i want to see feeds from only my friends.
Can any one help me how to achieve it. i am sharing the base level code of python and java script.
Client side:
var source = new EventSource("http://172.19.0.3:8044/events");
source.addEventListener('user_feeds', function(event) {
var data = JSON.parse(event.data);
console.log("Even from server ");
console.log(data);
}, false);
Server side
from flask_cors import CORS
from flask_sse import sse
from factory import create_app
app = create_app()
CORS(app)
app.config["REDIS_URL"] = "redis://redis"
input_user_feeds = dict()
app.register_blueprint(sse, url_prefix='/events)
PROMOTION_BLUEPRINT = Blueprint('my_page', __name__, url_prefix='/api/v1/')
#PROMOTION_BLUEPRINT.route('/feeds/<user_id>', methods=["GET"])
def feeds(user_id):
push_feeds(user_id)
return "SUCCESS"
#PROMOTION_BLUEPRINT.route('/user_request/<user_id>', methods=["POST"])
def user_request(user_id):
data = request.json
add_feeds(user_id, data)
return "SUCESS"
def push_feeds(user_id):
while 1 == 1:
if user_id in input_user_feeds:
input_request = input_user_feeds[user_id]
sse.publish(input_request, type='user_feeds')
del input_user_feeds[user_id]
def add_feeds(user_id, data):
input_user_feeds[user_id] = data
if __name__ == '__main__':
app.run(host='0.0.0.0', port=Config.PORT, debug=True)
I trued to do with single user id. but that is also not a good idea.
It will be helpful if anyone having good knowledge in SSE help me find the solution.
Thanks in advance.

Channel_not_found: authed_user cannot post a message to a channel via Slack API

I'm trying to post a message on a channel a user belongs via the Slack Api as an authed_user.
here is the flow:
User gives permissions with scopes 'chat:write,channels:write,channels:history'
I receive a token along with some more information from Slack that looks like xoxp-122474-a bunch of numbers
I create a Slack Client with the token and sends a request with:
const { WebClient } = require('#slack/web-api');
const client = new WebClient(token.access_token);
await client.chat.postMessage({
channel: channelId, // = Something similar to C02E2K5CCUZ
as_user: true,
text: "here is some text",
});
I get an error from the slack API, 'channel_not_found' but I checked the channel does exists + the user is in the channel.
What should I do to make this work? Am I missing anything?
Thank you !
It's possible that error is a red herring. The as_user parameter might be messing you up. That parameter can only be used for legacy apps. You can still use chat.postMessage but make sure you are also requesting the [chat:write.customize][1] scope. You will then be able to customize the posting user by defining the username and icon_urlparameters in your API call.

How to listen for Telegram Bot errors? (Google App Script + Webhooks)

I have developed a fully functional Telegram Bot with Google App Script that uses Webhooks to read and write into a Google Spreadsheet.
Although the bot is stable, sometimes it crashes due to specific user interaction like pressing buttons too fast or making the bot send too many messages in a short amount of time.
The Error Handling section of the Telegram API mentions that errors are returned in rpc_error constructors, but there is no reference to any method that can be used to listen for any error that may occur.
I want to handle these errors but the only way I am aware is to listen for errors on each API request.
Here is an example of how I am handling an error right now:
function editKeyboardMessage(buttonArray) {
var id = PropertiesService.getUserProperties().getProperty("inline_form_chat_id");
var message_id = PropertiesService.getUserProperties().getProperty("inline_form_message_id");
var keyboardMarkup = {"inline_keyboard": buttonArray};
var data = {
method: "post",
payload: {
method: "editMessageReplyMarkup",
chat_id: String(id),
message_id: Number(message_id),
parse_mode: "HTML",
reply_markup: JSON.stringify(keyboardMarkup)
}
};
var response = UrlFetchApp.fetch(url + "/", data)
var responseCode = response.getResponseCode()
handleErrors(responseCode)
}
However, it seems unpractical to do this on all requests types and it doesn't allow complete error handling (like the ones that happen independently of requests, such as message flooding).
The expected outcome would be to properly handle all incoming errors in just one place.
Is there a way to listen for all bot errors with something similar to the doPost(e) function that is used to listen for updates?
Since we are currently talking on Telegram - it might be helpful for others.
The conversation started at https://t.me/BotTalk/105298
tl;dr you need to do error handling on your end. If you don't use a library, try checking each response from Telegram after sending out a request for errors. If there are errors, handle them accordingly.

Sending data from JavaScript to Python function locally with AJAX

I am trying to build a website where a user can enter text, which will be picked up via javascript, and sent to a python function where it will be posted to twitter. For the time being, the python function is being stored locally, along with the rest of the site. However, my AJAX isn't too great and I'm having a few issues.
I have written AJAX code which sends a POST request to the python function with the tweet, and the response is the entire python script. No connection is made to the socket my script is listening to. Below is the AJAX function and the python script. Any ideas what's going on?
Thanks in advance for any help!
$(function(){
$('#PostTweet').on('click', function(e) {
var tweet = document.getElementById("theTweet").value;
var len = tweet.length;
if(len > 140){
window.alert("Tweet too long. Please remove some characters");
}else{
callPython(tweet);
}
});
});
function callPython(tweet){
window.alert("sending");
$.ajax({
type: "POST",
url: "tweet.py",
data: tweet,
success: function(response){
window.alert(response);
}
})
}
And the Python Script:
from OAuthSettings import settings
import twitter
from socket import *
consumer_key = settings['consumer_key']
consumer_secret = settings['consumer_secret']
access_token_key = settings['access_token_key']
access_token_secret = settings['access_token_secret']
s = socket()
s.bind(('', 9999))
s.listen(4)
(ns, na) = s.accept()
def PostToTwits(data):
try:
api = twitter.Api(
consumer_key = consumer_key,
consumer_secret = consumer_secret,
access_token_key = access_token_key,
access_token_secret = access_token_secret)
api.PostUpdate(data)
makeConnection(s)
except twitter.TwitterError:
print 'Post Unsuccessful. Error Occurred'
def makeConnection(s):
while True:
print "connected with: " + str(na)
try:
data = ns.recv(4096)
print data
PostToTwits(data)
except:
ns.close()
s.close()
break
makeConnection(s)
Your problem is that you are working with pure sockets which know nothing about HTTP protocol. Take a look at Flask or Bottle web micro frameworks to see how to turn python script or function into web endpoint.
you need a webserver so that your can make request via web browser.
you can web framework like flask or django or you can use webpy.
A simple example using webpy from their website
import web
urls = (
'/(.*)', 'hello'
)
app = web.application(urls, globals())
class hello:
def GET(self, name):
if not name:
name = 'World'
return 'Hello, ' + name + '!'
if __name__ == "__main__":
app.run()
then you call url(your python function) from javascript.
You can totally write a simple web server using sockets, and indeed you've done so. But this approach will quickly get tedious for anything beyond a simple exercise.
For example, your code is restricted to handling a single request handler, which goes to the heart of your problem.
The url on the post request is wrong. In your setup there is no notion of a url "tweet.py". That url would actually work if you were also serving the web page where the jquery lives from the same server (but you can't be).
You have to post to "http://localhost:9999" and you can have any path you want after:"http://localhost:9999/foo", "http://localhost:9999/boo". Just make sure you run the python script from the command line first, so the server is listening.
Also the difference between a get and a post request is part of the HTTP protocol which your simple server doesn't know anything about. This mainly means that it doesn't matter what verb you use on the ajax request. Your server listens for all HTTP verb types.
Lastly, I'm not seeing any data being returned to the client. You need to do something like ns.sendall("Some response"). Tutorials for building a simple http server abound and show different ways of sending responses.

Pusher subscribe and un-subscribe process

I'm getting a Pusher subscribe/un-subscribe problem with presence groups on a fairly simple chat application. There should be two subscribed channels at a given time. Users switch between channels when navigating between backbone routes, so there are no hard page reloads.
Pusher appears to function most of the time, but I get intermittent errors for channel subscriptions.
I wrote two join channel methods that unsubscribe if one has been joined by a previous route. I'm worried that there is something async happening within Pusher that is breaking things.
My pusher related code for a single channel:
window.pusher = new Pusher('<%= Pusher.key %>', {
authEndpoint: 'api/pusher/auth'
});
Route:
this.groupFeed = this._pusherSubscribeGroup(group_id);
this.groupFeed.bind('new_conversation', function(data) {
var newConv = new App.Models.Conversation(data);
this.group.conversations().add(newConv);
}.bind(this));
Unsubscribe helper:
_pusherSubscribeGroup: function (group_id) {
if (this._groupChannelName) {
window.pusher.unsubscribe(this._groupChannelName);
}
this._groupChannelName = 'presence-group-' + group_id;
return window.pusher.subscribe(this._groupChannelName);
}
Console error:
Pusher : Error : {"type":"WebSocketError","error":{"type":"PusherError","data":{"code":null,"message":"Existing subscription to channel presence-group-1"}}}
Pusher : Error : {"type":"WebSocketError","error":{"type":"PusherError","data":{"code":null,"message":"Existing subscription to channel presence-group-1"}}}
The message is telling you that - as far as the Pusher service is concerned - this particular client identified by a socket_id is already subscribed to the presence-group-1 channel. From the point of view of the client this error normally isn't something you actually need to worry about.
However, if the user is quickly subscribing/unsubscribing by navigating routes it would be worth getting some more information to be completely sure. From the supplied code and description, it's not possible to determine if the problem is within the Pusher service or the client application.
Providing the output of the Pusher JavaScript library logging will provide more detail that could help determine the cause.

Categories

Resources