send ejabberd push notification ( django ) - python

I have integrated ejabberd for chat functionality. Apps backend is in python-django and frontend is in IOS. current flow is as follows :
When user signup into my app, A record has been created for that user in ejabberd server. This thing is handled in backend. unique id for that user is the combination of primary key and name ( e.g - 123_mark#xyz.com )
To chat on frontend , IOS is using these id's. When both users are online , they can chat successfully.
Problem - When a user gets offline or a user kills the application, Then backend has to send notifications to device. I have checked ejjaberd's documentation. According to them I have to use mod_zeropush to send notifications. I have checked some articles, but I am not sure how to send notification to users. Can someone explain it in detail.

As far as I can see ZeroPush mod leverages a ZeroPush server, I might be wrong about this as I just glanced through their pages.
What you need to do is to create your own mod which hooks into events that are occurring in ejabberd. This Q&A sums it up: How to develop custom functions on top of Ejabberd?
Basically you need to find out which event is fired when a user disconnects and hook into that event so your mod would be executed.

Related

Django - Restrict Stripe SuccessUrl access

I have just integrated Stripe Checkout with my Django app. However, from their code:
session = stripe.checkout.Session.create(
customer_email=customer.email,
payment_method_types=['card'],
line_items=line_items,
mode='payment',
success_url='http://127.0.0.1:8000/SUCCESS/?session_id={CHECKOUT_SESSION_ID}',
cancel_url='http://127.0.0.1:8000/cart'
)
It redirects to a Success_url. I would like to display their order info and send an email from the success page but currently, everyone can visit(would cause random emails etc). Is there a way i can limit this for the person that just checked out? Thank you!
The success page should really just be a page to let your users know that their payment went through. I wouldn't personally recommend triggering any app-specific logic when your users land on it. As you've pointed out this could cause accidents with users randomly stumbling on that page and triggering emails. It also offers an opportunity for bad actors to exploit your application.
Instead, I would create a webhook endpoint and listen for the checkout.session.completed event, and trigger your emails from there. Building a webhook endpoint should be no more difficult than building any other endpoint on your server, with there only being some small extra logic to verify incoming requests.
Another option would be to use a tool like Zapier to listen for these events from Stripe and trigger various flows from them: https://stripe.com/partners/zapier

Change status of an XMPP user in Django using ejabberd

I want a Functionality where If a user change his status, that status needs to reflect at runtime (like Whatsapp). My App is in IOS and Android and backend is in Django.
I am advised to use ejabberd server for this as tt supports XMPP protocol.
I am not sure how to implement this functionality. Can anyone guide me?
There is many ways in XMPP to express the state of the user:
presence: It allows you to convey both the availability of the user (among predefined "show" elements: Available, Away, Do not Disturb, etc) and your status (Free form text). However, presence is related to the user session and suppose he has an XMPP session open (and thus is connected). It means it is intended to be set by user from client, not from backend and is only broadcast to contacts when the user is online.
Last activity: This is something that complement XMPP presence. It is a way to get user state information when the user is offline. I would recommend to use that to get more familiar with XMPP. To integrate with your back-end, I would setup ejabberd to store last activity in database and to update it in database from your backend. User that need to read it (For example when a conversion tab is opened) can display the XMPP if the user is online, or the last activity if the user if offline. You can also just let the user set its own status on last presence when getting unavailable (offline). It will be automatically updated in the last table by ejabberd.
mood: This is something used to express state in a more complete way. User can set mood with more richer status and the mood is not tight to presence. However, it is a bit more complex to integrate with backend as it is based on the PubSub protocol.
To summarize, in your case, you can use a mix of standard XMPP presence and Last activity with change of status from backend.

how to authenticate users with django ejabberd bridge

I am trying to integrate ejabberd with django authentication. I am following instructions on: https://github.com/ffalcinelli/django-ejabberd-bridge
I have followed every step.
I have defined the path of the script for authentication
{auth_method, external}.
{extauth_program, "script.sh"}. ( I have defined full path here )
Script file's content is :
#!/bin/bash
source <path>/env/bin/activate
python <path>/manage.py ejabberd_auth $#
My Problem is that I want ejjaberd to maintain the state of every user ( online , offline , away etc ). I think that whenever a user will login ( or logout ), that data needs to be sent to ejjaberd server. I tried to login and logout, but these users are not registering at ejabberd ( localhost:5280/admin )
I have tried this command from console :
python manage.py ejabberd_auth $#
It should ask me username and password. In the log file there is only one log :
2015-08-03 08:11:05,791 [DEBUG] ejabberd_bridge.management.commands.ejabberd_auth: Starting serving authentication requests for eJabberd
How can I send the user data to ejabberd?
You are expecting too much feature from that authentication module.
django-ejabberd-bridge purpose is to let ejabberd check authentication against Django authentication middleware, as described in project README:
Right now it just allows the ejabberd service to perform
authentication against Django's authentication middleware.
This has nothing to do with changing presence for example. That bridge will be use in that worklow:
a user want to log in ejabberd using XMPP client
ejabberd use external auth, thus your script for Django bridge to check if user and credentials are valid.
ejabberd use the result of the script to either accept or reject the user authentication request.
That's it. Presence and user state is still managed as usual with XMPP. While XMPP session is open, user will be seen as online. When XMPP client disconnect, user will be seen as offline by ejabberd, etc.
The user database is not duplicated. It is kept in the backend service. That's also the reason why user cannot be listed from the web interface: ejabberd does not handle them.
If you want only the presence of the user state, the django-ejabberd-bridge can manage it. you can see the online users in the web admin interface http://localhost:5280/admin/server/localhost/online-users/. But in your point of registering the user, the django-ejabberd-bridge doesn't do that. If you want to register the user from django to XMPP, then you should query it with the javascript libraries like converse.js, strophe.js etc.
I haven't tried registering the user using converse.js. Strophe provide the plugin called strophe.register.js for registering the users.

Passing session info from python to flex

I have a simple site made with python (django). User registers, inputs some basic info and it stores it to mysql. User then is able to log in with his username/password which he created...
Now i want to add a flex application which will run once the user is logged in, but i dont want the user to have to log in twice (once into django, once into flex app). For the sake of learning i just want the flex app to also load some information from the mysql database, like the users firstname or something.
So my question is how would i go about passing session information into the flex app? Any info or guidance, or opinion would be great.
If your Python/DJango app uses cookies for tracking sessions; then you just have to make sure that your SWF is served off the same domain that the Python app is served from.
The Flash Player will pass the appropriate cookies to the remote server whenever it makes a call to that server. As long as your "Flash Call" exists in the same Application space on the server, it should have access to the same session variables available on the server.
If you want to validate the user has logged in before loading the SWF; just make a remote call from the SWF to the server side to validate that the session exists, and the user is appropriately logged in. Don't activate any of the controls in the app until you get confirmation from the server that the user is allowed to use the app.

XMPP based live-chat system in Django

I need to implement an XMPP based live-chat system in Django. After a lot of scourging and ideas from a colleague, we came up with this.
Method using a bot:
When a visitor visits the site. The visitor's XMPP client which in this case is Strophe.JS begins an XMPP-over-BOSH connection to the XMPP server and connects to a room called <visitor_id>#conference.demo.com. Currently there is no one else in the room.
The visitor makes an analytics request with a custom visitor id to Django
The Django view, stores the visitor id in a table called ActiveUsers. This table contains a new field as well called status. It sets the status to INACTIVE.
This model dispatches a signal on the save method.
This signal gets picked up by a bot which connects to the XMPP server and joins the room <visitor_id>#conference.demo.com. Now we have the user and the bot in the room.
The site support people are logged into their web interface.
They have JS code that keeps long-polling the Django site to check the ActiveUsers. It fetches the rows from the table and displays it. (I've thought of using django-pubsub for this)
When the visitor types a message, it goes via XMPP-over-BOSH to the XMPP server, the jabber bot in the room see this message and updates the status of the record in the ActiveUsers table to ACTIVE.
As said: The site support people have JS which keeps polling this table. It begins blinking the ow to show that the user is now chatting.
The support personnel can now double-click that row which on doing so begins an XMPP-over-BOSH connection to the visitor's room. It knows that the room is <visitor_id>#conference.demo.com.
The bot seeing that the support person has joined the room, updates ActiveUsers record to show CHATTING. This ensures that no more than support personnel can be in the room i.e. room occupied.
The bot logs the messages to a Django table
When the both sees that both users have left the room, it deletes the record.
ejabberd or openfire will be XMPP server.
Apache is the web server which runs mod_wsgi for serving Django and mod_proxy for proxying the XMPP-over-BOSh requests to the XMPP server.
Does this sound like a good of doing this? Any suggestions? I'm worried about the load on the Django system.
(It's long. Sorry 'bout that.)
Method using Presence Stanzas:
On the client side, i'm using Strophe JS library which supports presence and I had add callback methods. I'm flexible with using ejabberd or openfire as my XMPP server. The are many visitors on the XMPP server — some from site A and some from site B but they are all connected to the same XMPP server. When the visitor visits the site, they are connected to the XMPP server as <visitor_id>_<site_id>#demo.com and each one gets logged into a room called <visitor_id>#conference.demo.com. The sales/support personnel are also connected to the XMPP sever as <supportsale_id>_<site_id>#demo.com. They are not connected to any chat room though. They don't have any of the visitors on their roster.
A good way of showing that a user has connected to the site would be to pass a presence stanza to the sales/support people. Only visitors and sale/support personnel from the same site communicate with each other and that's why I have the <site_id> in the username to show which site that person belongs to.
It seems that you can't subscribe to presence stanzas for a user if you don't have him on your roster. (Quite logical). Is is possible to automatically add every new user of a site connecting to the system to the roster of the sales/support people of that site? Wouldn't this then automatically signal a presence to the sales/support people? How can I implement this — any help?
I wrote exactly this. It's called Seshat and uses a "broker" bot between the website and a Jabber server (I use ejabberd). It's in beta right now mainly because it hasn't been extensively tested outside my company.
Note: while the README specifically mentions the Pyramid web framework, the core system would work just as well with a Django, TurboGears, or command line system. It's just that I only package example code showing how to integrate it with Pyramid.
Seshat is being actively developed. If you have any feature requests, let me know. :-)
I'm not sure you need to use MUCs to implement this. Your bot could maintain its own pubsub node which it is subscribed to. When a new user begins to type it could send a notification to the pubsub node, which the bot would then see. From there, the bot could notify a support person via XMPP, thus eliminating the need to long poll the database table. Then the support person could start a standard one to one chat session with the end user. In addition, their presence could be set to 'na' in order to show that they are in a session with a user.
I think that it's better to use presence stanzas to "signal" any (in)activity. What you need to store in database is only the persistent data you need for further analysis. Otherwise, I think you'll have great time coding the application :).
EDIT:
function onConnect(status) {
if (status == Strophe.Status.CONNECTED) {
var joined = false;
var participants = {};
$('#events').html('<text class="textmainleft">XMPP connection established. Ready to rock n roll!</text>');
connection.send($pres().c('priority').t('-1'));
connection.addHandler(notifyUser, null, 'message', 'groupchat', null, null);
connection.send($pres({to: 'groupchatroom#conference.demo.com/' + nickname}).c('x', {xmlns: 'http://jabber.org/protocol/muc'}));
} else if (status == Strophe.Status.AUTHFAIL) {
$(location).attr('href', AUTHFAIL_URL);
} else if (status == Strophe.Status.CONNFAIL) {
$(location).attr('href', AUTHFAIL_URL);
}
}
$(document).ready(function () {
connection = new Strophe.Connection(BOSH_SERVICE);
connection.connect(jid, password, onConnect);
});
notifyUser is another function (just link onConnect) that would handle the received message stanzas.

Categories

Resources