Configura notificaciones push en Django con OneSignal
Recientemente comencé a investigar un poco sobre cómo configurar las Notificaciones Push para un proyecto, lo primero que comencé a leer fué Google Firebase, luego de una horas de lectura decidí por cuestiones de tiempo buscar alguna librería de Django que me pudiera simplificar el trabajo y desarrollar esta funcionalidad lo más rápido posible.
Luego de investigar me dí cuenta que las librerías que habían no tenían una documentación muy extensa y con detalles como ésta por ejemplo: https://github.com/xtrinch/fcm-django, así que decidí desarrollar un código simple que se adaptara a las necesidades del proyecto. He de mencionar que tuve suerte de conseguir una web que simplifica muchísimo el trabajo con Firebase y decidí utilizarla https://app.onesignal.com/login
Ya puesto a trabajar el código que logré desarrollar quedó así:
Primero debes seguir las instrucciones de la web -> Instrucciones
Lo más importante es insertar correctamente la url y la ruta a los archivos de la app en el servidor de tu web.
El primer paso es insertar el código en la página donde necesites registrar a tus usarios para recibir las notificaciones, en mi caso particular sólo los usuarios registrados pueden ser agregados.
en la página inicial de los usuarios he colocado este código:
<script src="https://cdn.onesignal.com/sdks/OneSignalSDK.js" async=""></script>
<script>
var OneSignal = window.OneSignal || [];
var initConfig = {
appId: "TU APP ID",
notifyButton: {
enable: true
},
};
OneSignal.push(function () {
OneSignal.SERVICE_WORKER_PARAM = { scope: '/static/backend/onesignal/' };
OneSignal.SERVICE_WORKER_PATH = 'static/backend/OneSignalSDKWorker.js'
OneSignal.SERVICE_WORKER_UPDATER_PATH = 'static/backend/OneSignalSDKUpdaterWorker.js'
OneSignal.init(initConfig);
});
OneSignal.push(function() {
OneSignal.getUserId(function(userId) {
console.log("OneSignal User ID:", userId);
// (Output) OneSignal User ID
$.post("/onesignal_register/",
{
playerId: userId,
csrfmiddlewaretoken: "{{ csrf_token }}",
},
function(data, status){
console.log("Data: " + data + "\nStatus: " + status);
});
});
});
</script>
Explico por partes:
1.- Primero cargo el script del cdn para tener disponible la librería
2.- Inicio la configuración de los "workers" de la aplicación con una ruta específica a la carpeta de "static", así el servidor de oneSignal sabe donde conseguir los archivos. Aquí tienes el manual -> Manual
3.- Usando Ajax hago un post a la url /onesignal_register/ que es donde tengo configurada la vista que registra el onesignal_playerId del usuario logueado en la base de datos.
En models.py tengo dentro de la clase Profile un campo llamado así:
onesignal_playerId = models.CharField(max_length=50, blank=True, null=True)
En views.py:
Si sabes de Django ya te habrás dado cuenta que uso un Profile para guardar la información extra, si no sabes de esto te recomiendo mirar esta info -> Django extensión del model User
def onesignal_register(request):
'''función que registra la playerId del usuario logueado'''
profile = Profile.objects.get(user=request.user)
if request.POST.get('playerId'):
if profile.onesignal_playerId == request.POST.get('playerId'):
return HttpResponse('La id es la misma')
else:
profile.onesignal_playerId = request.POST.get('playerId')
profile.save()
return HttpResponse('La id es nueva o ha cambiado')
else:
return HttpResponse('Algo ha ido mal')
En esta vista verifico si el usuario ya tiene una playerId asignada y si la que tiene registrada el explorador es igual a la registrada en la BD no se realiza ningún cambio.
En el archivo urls.py:
path('onesignal_register/', views.onesignal_register, name='registro-onesignal
Agrego la ruta a la vista que agrega la id de OneSignal del usuario.
Así cuando un usuario está logueado por primera vez verá lo siguiente:
Luego al aceptar:
Todos estos mensajes se puede personalizar en la web de OneSignal.
A partir de aquí ya el usuario puede recibir las notificaciones que envíes indiferentemente si tiene la aplicación abierta o no ya que el identificador se queda guardado en una cookie, en caso de que el usuario borre las cookies no pasa nada ya que la app registra la nueva onesignal_id en la BD.
Luego para enviar mensajes es muy fácil, el código:
def send_notification_rider(onesignalid_rider, cliente):
"""Función que envía el mensaje push al rider"""
header = {"Content-Type": "application/json; charset=utf-8",
"Authorization": "Basic "+ settings.ONESIGNAL_KEY}
payload = {"app_id": "tu_app_id",
"include_player_ids": [onesignalid_rider],
"contents": {"en": "Tienes un pedido nuevo en: "+cliente}}
requests.post("https://onesignal.com/api/v1/notifications", headers=header, data=json.dumps(payload))
return HttpResponse('El mensaje ha sido enviado')
Si te fijas bien no he puesto la ApiKey de la app directamente si no que he usado una variable de entorno, para cuestiones pruebas locales simplemente pones aquí la api key.
Esta función recibe la onsegisnal_id_rider del usuario receptor del mensaje y luego en cliente simplemente inserto una dirección que incluyo en el cuerpo del mensaje.
El cuerpo del mensaje va declarado en "contents" luego de la palabra "en". Dentro del mismo agrego la dirección que he mencionado anteriormente con la variable "cliente".
Luego esta función puedes usarla en cualquier etapa de los procesos de tu aplicación, en este caso solamente envío la notificación a una ID en "include_player_ids" pero OneSignal te permite enviar notificaciones a todos los suscriptores que tengas, es cuestión de ver sus manuales.
Espero que te sirva de mucho la lección, si te ha gustado déjame un mensaje o comparte el artículo para que más personas puedan aprovechar la info, ¡Gracias!