Package: django-channels-notifications
Django Channels NotificationsNotifying users of various things that happen in your application is super easy to implement. Django Channels notifications allow you to send a message to any user via Email, Datbase, and many other channels.InstallationRun thepipcommand to install the latest version:pipinstalldjango-channels-notificationsAdddjango_channels_notificationsto yourINSTALLED_APPSin settings.py:INSTALLED_APPS=(...'django_channels_notifications',)Run the migration command:pythonmanage.pymigrateCreating NotificationsIn Django Channels Notifications, each notification is represented by a single class, and to create a new notification you can run the following manage.py command:pythonmanage.pycreatenotificationTestNotificationAnd this will place a fresh notification class with the below contents. Each notification class contains aviamethod and a variable number of message building methods (such asto_mailorto_database) that convert the notification to a message optimized for that particular channel.fromdjango_channels_notifications.coreimportNotificationfromdjango_channels_notifications.core.channelsimportDatabaseChannelclassTestNotification(Notification):# Get the notification's delivery channels.defvia(self,notifiable):return[DatabaseChannel]# Get the dict representation of the notification.defto_database(self,notifiable):passSending  Notifications# Using The Notifiable MixinNotifications may be sent in two ways: using the notify method of the Notifiable mixin or using the NotificationSender . First, let's explore using the mixin:fromdjango_channels_notifications.coreimportNotifiablefromdjango.dbimportmodelsclassProfile(models.Model,Notifiable):phone=models.CharField(max_length=255,verbose_name='Phone')address=models.TextField(max_length=512,verbose_name='Address')AddingNotifiablemixin in yourProfilemodel will allow you to easily send notifications to profiles usingnotifymethod. Thenotifymethod expects to receive a notification instance:profile=Profile.objects.get(pk=1)profile.notify(TestNotification());Remember ,you may use thedjango_channels_notifications.core.Notifiablemixin on any of your models. You are not limited to only including it on yourProfilemodel.# Using The NotificationSender:Alternatively, you may send notifications via theNotificationSender. This is useful primarily when you need to send a notification to multiple notifiable entities such as a list of profiles. To send notifications using the NotificationSender, pass all of the notifiable entities and the notification instance to thesendmethod:fromdjango_channels_notifications.coreimportNotificationSenderprofiles=Profile.objects.all()NotificationSender.send(profiles,TestNotification())# Specifying Delivery Channels:Every notification class has aviamethod that determines on which channels the notification will be delivered. Notifications may be sent on thedatabase,mail,unifoncchannels.Theviamethod receives anotifiableinstance, which will be an instance of the class to which the notification is being sent. You may usenotifiableto determine which channels the notification should be delivered on:#Get the notification's delivery channels.defvia(self,notifiable):ifnotifiable.prefers_sms:return[UnifonicChannel]return[DatabaseChannel]Let's quickly go through the different notification channels supported by Django Channels Notifications.Database:This option allows you to store notifications in a database should you wish to build a custom UI to display it.Mail:The notifications will be sent in the form of email to users.Unifonic:As the name suggests, users will receive SMS notifications on their phone.Database ChannelTheDatabaseChannelnotification stores the notification information in a database table. This table will contain information such as the notification type as well as custom JSON data that describes the notification.# Formatting Database Notifications:If a notification supports being stored in a database table, you should define ato_databasemethod on the notification class. This method will receive anotifiableentity and should return a plain Python dict. The returned dict will be encoded as JSON and stored in thedatacolumn of yournotificationstable. Let's take a look at an exampleto_databasemethod:# Get the dict representation of the notification.defto_database(self,notifiable):return{'invoice_id':12,'amount':200,}# Accessing The NotificationsOnce notifications are stored in the database, you need a convenient way to access them from your notifiable entities. To fetch notifications, you may use thenotificationsmethod. By default, notifications will be sorted by thecreated_attimestamp:profile=Profile.objects.get(pk=1)fornotificationinprofile.notifications():print(notification.type)If you want to retrieve only the "unread" notifications, you may use theunread_notificationsmethod and If you want to retrieve only the "read" notifications, you may use theread_notificationsmethod. Again, these notifications will be sorted by thecreated_attimestamp:profile=Profile.objects.get(pk=1)fornotificationinprofile.unread_notifications():print(notification.type)fornotificationinprofile.read_notifications():print(notification.type)# Marking Notifications As Read , Unread:Typically, you will want to mark a notification as "read" when a user views it. Thedjango_channels_notifications.core.notifiablemixin providesmark_as_readandmark_as_unreadmethods, which updates theread_atcolumn on the notification's database record:profile=Profile.objects.get(pk=1)# Marking notifications as readfornotificationinprofile.unread_notifications():notification.mark_as_read()# Marking notifications as unreadfornotificationinprofile.read_notifications():notification.mark_as_unread()Mail ChannelIf a notification supports being sent as an email, you should define ato_mailmethod on the notification class. This method will receive anotifiableentity and should return adjango.core.mail.EmailMessageordjango.core.mail.EmailMultiAlternativesinstance. Let's take a look at an exampleto_mailmethod:fromdjango.core.mailimportEmailMessage# Get the mail representation of the notification.defto_mail(self,notifiable):returnEmailMessage('Hello','Body goes here','from@example.com',['to1@example.com','to2@example.com'],['bcc@example.com'],reply_to=['another@example.com'],headers={'Message-ID':'foo'},)# Sending through "Mailgun" :To use the Mailgun provider,  you need to add the following parameters to yoursettings.py:EMAIL_HOST='smtp.mailgun.org'EMAIL_PORT=587EMAIL_HOST_USER='postmaster@msg.com'#please change this with your usernameEMAIL_HOST_PASSWORD='112233445566778899'#please change this with your passwordEMAIL_USE_TLS=True# Sending through "SES" :To use the SES provider, you'll needBoto2.1.0 or higher.Botois a Python library that wraps the AWS API.You can do the following to install boto 2.1.0 (we're using --upgrade here to make sure you get 2.1.0):pipinstall--upgradebotoInstall django-ses:pipinstalldjango-sesAdd the following to your settings.py:EMAIL_BACKEND='django_ses.SESBackend'# These are optional -- if they're set as environment variables they won't# need to be set here as wellAWS_ACCESS_KEY_ID='YOUR-ACCESS-KEY-ID'AWS_SECRET_ACCESS_KEY='YOUR-SECRET-ACCESS-KEY'# Additionally, if you are not using the default AWS region of us-east-1,# you need to specify a region, like so:AWS_SES_REGION_NAME='us-west-2'AWS_SES_REGION_ENDPOINT='email.us-west-2.amazonaws.com'Unifonic ChannelTheUnifonicChannelnotification allow you to sent the notification as SMS via Unifonic.You need to addUNIFONIC_APPSIDin settings.py:UNIFONIC_APPSID="Your Unifonic APPSID"# Formatting Unifonic Notifications:If a notification supports being sent as an SMS, you should define ato_unifonicmethod on the notification class. This method will receive anotifiableentity and should return adjango_channels_notifications.core.channels.unifonic_channel.UnifonicMessageinstance:fromdjango_channels_notifications.core.channels.unifonic_channelimportUnifonicMessage# Get the Unifonic representation of the notification.defto_unifonic(self,notifiable):returnUnifonicMessage().set_body('Your SMS message content').set_recipient(notifiable.phone)# Customizing The "SenderID":If you would like to send some notifications from a SenderID that is different from the default SenderID in your  Unifonic account, you may use theset_sender_idmethod on aUnifonicMessageinstance:fromdjango_channels_notifications.core.channels.unifonic_channelimportUnifonicMessage# Get the Unifonic representation of the notification.defto_unifonic(self,notifiable):returnUnifonicMessage().set_body('Your SMS message content').set_recipient(notifiable.phone).set_sender_id('Your SenderID')Custom ChannelsDjango Channels Notifications ships with a handful of notification channels, but you may want to write your own channel to deliver notifications via other channels. Django Channels Notifications makes it simple. To get started, define a class that extended fromdjango_channels_notifications.core.BaseChanneland contains asendmethod. The method should receive two arguments: anotifiableand anotification. or by run the following manage.py command:pythonmanage.pycreatechannelTestChannelfromdjango_channels_notifications.coreimportBaseChannelclassTestChannel(BaseChannel):# Send the given notification.defsend(self,notifiable,notification):passOnce your notification channel class has been defined, you may return the class name from theviamethod of any of your notifications:classTestNotification(Notification):# Get the notification's delivery channels.defvia(self,notifiable):return[DatabaseChannel,TestChannel]# Get the dict representation of the notification.defto_database(self,notifiable):pass# Get the dict representation of the notification.defto_test(self,notifiable):pass