BaseApp Notifications
Project description
BaseApp Notifications
Reusable app to have in-app notifications integrated with email and push notifications. Its built on top of django-notifications-hq.
Based on the Activity Streams Spec.
Notifications are actually actions events, which are categorized by four main components.
Actor
. The object that performed the activity.Verb
. The verb phrase that identifies the action of the activity.Action Object
. (Optional) The object linked to the action itself.Target
. (Optional) The object to which the activity was performed.
Actor
, Action Object
and Target
are GenericForeignKeys
to any
arbitrary Django object. An action is a description of an action that
was performed (Verb
) at some instant in time by some Actor
on some
optional Target
that results in an Action Object
getting
created/updated/deleted.
For example: nossila (actor)
opened (verb)
pull request
18
(action_object)
on
baseapp-backend
(target)
12 hours ago
Whats missing
- Finish implementing push notifications
- DRF views and serializers
How to install
Requirements:
- baseapp-core >= 0.2.0
- django-notifications-hq >= 1.8
- **django-push-notifications >= 3.0.2
Run pip install baseapp-notifications
And make sure to add the frozen version to your requirements/base.txt
file
If you want to develop, install using this other guide.
Setup In-App notifications
1 - Add to your INSTALLED_APPS
:
INSTALLED_APPS = [
"baseapp_notifications",
]
2 - Set the notification model in your settings/base.py
:
NOTIFICATIONS_NOTIFICATION_MODEL = "baseapp_notifications.Notification"
Check how to customize to your own model bellow.
3 - Make sure to add the task routing for send_push_notification
CELERY_TASK_ROUTES = {
"baseapp_notifications.tasks.send_push_notification": {
"exchange": "default",
"routing_key": "default",
},
}
4 - Make sure that your main User
's DjangoObjectType
implements interface NotificationsInterface
:
from baseapp_core.graphql import DjangoObjectType
from baseapp_notifications.graphql.object_types import NotificationsInterface
class UserNode(DjangoObjectType):
class Meta:
interfaces = (relay.Node, NotificationsInterface)
5 - Then you can expose notification's mutations and subscriptions:
import graphene
from baseapp_notifications.graphql.mutations import NotificationsMutations
from baseapp_notifications.graphql.subscriptions import NotificationsSubscription
class Query(graphene.ObjectType):
me = graphene.Field(UserNode)
def resolve_me(self, info):
if info.context.user.is_authenticated:
return info.context.user
class Mutation(graphene.ObjectType, NotificationsMutations):
pass
class Subscription(graphene.ObjectType, NotificationsSubscription):
pass
schema = graphene.Schema(query=Query, mutation=Mutation, subscription=Subscription)
Setup Push notifications (apple and google)
1 - Add to your INSTALLED_APPS
:
INSTALLED_APPS = [
"push_notifications"
]
2 - Set the push notifications settings in your settings/base.py
:
PUSH_NOTIFICATIONS_SETTINGS = {
"FCM_API_KEY": "[your api key]",
"APNS_CERTIFICATE": ["Absolute path to your APNS certificate file"],
"APNS_TOPIC": ["Apple app ID"],
"DEFAULT_CLOUD_MESSAGE_TYPE": "FCM",
"UPDATE_ON_DUPLICATE_REG_ID": True/False,
"APNS_USE_SANDBOX": True/False,
}
You can get more details about this settings dict at the django-push-notifications oficial repository.
3 - Set the push notification routes in your router.py
from push_notifications.api.rest_framework import ( # noqa
APNSDeviceAuthorizedViewSet,
GCMDeviceAuthorizedViewSet,
WNSDeviceAuthorizedViewSet,
WebPushDeviceAuthorizedViewSet,
)
router.register(r"push-notifications/apns", APNSDeviceAuthorizedViewSet, basename="apns")
router.register(r"push-notifications/gcm", GCMDeviceAuthorizedViewSet, basename="gcm")
router.register(r"push-notifications/wns", WNSDeviceAuthorizedViewSet, basename="wns")
router.register(r"push-notifications/web", WebPushDeviceAuthorizedViewSet, basename="web")
How to send a notification
from baseapp_notifications import send_notification
send_notification(
add_to_history=True,
send_push=True,
send_email=True,
sender=user,
recipient=user,
verb="opened",
action_object=pr,
target=repository,
level="info",
description=_("{user_name} opened a pull request in {repository_name}").format(
user_name=user.name,
repository_name=repository.name
),
push_title=_("title"),
push_description=_("description"),
extra={},
)
Arguments:
- add_to_history: A boolean (default=True). True to add this to your in-app notifications history.
- send_push: A boolean (default=True). True to send push notification to user's devices.
- send_email: A boolean (default=True). True to send notification via email.
- sender: An object of any type. (Required)
- recipient: A Group or a User QuerySet or a list of User. (Required)
- verb: An string. (Required)
- action_object: An object of any type. (Optional)
- target: An object of any type. (Optional)
- level: One of Notification.LEVELS ('success', 'info', 'warning', 'error') (default=info). (Optional)
- description: An string. (Optional)
- notification_url: URL used in emails so users can open this notification's page. (Optional)
- email_subject: An string (default=description). This will override the email's subject message. (Optional)
- email_message: An string (default=description). This will override the email's body message. (Optional)
- public: An boolean (default=True). (Optional)
- timestamp: An tzinfo (default=timezone.now()). (Optional)
- push_description: A string. (Required). The "body" of your push notification
- push_title: A string. (Optional). This will override the Title of your notification (apple and google uses the name defined on your build files)
- extra: A dict with data of any type. (Optional)
Extra data: ou can also send any arbitrary kwargs and they will be added to Notification.data
JSONField.
Email notifications
To send email notifications make sure to set send_email=True
argument and notification_url
so users can open the notification in the browser. The description
will be used both as email's subject and email's body by default, check how to customize bellow.
send_notification(
sender=user,
recipient=user,
verb="opened",
description="email's subject",
add_to_history=True,
send_email=True,
notification_url="https://github.com/silverlogic/baseapp-backend/pull/18",
)
How to customize email notification templates
By default it will look for templates based in your slugify(verb)
, so can implement the following files with the following content in your project for each verb you want to customize:
Create templates/emails/notifications/{verb_slugified}-subject.txt.j2
with:
{% include "emails/notification-subject.txt.j2" %}
Create templates/emails/notifications/{verb_slugified}-body.txt.j2
with:
{% extends "emails/notification-body.txt.j2" %}
Create templates/emails/notifications/{verb_slugified}-body.html.j2
with:
{% extends "emails/notification-body.html.j2" %}
You can copy the extended templates over to your project to customize them as well.
Also check their source code in this repository to understand how you can customize the notification message for each notification's verb, for example, to customize the email notification message (defaults to what you passed to description
):
Example
{# templates/emails/notifications/opened-body.html.j2 #}
{% extends "emails/notification-body.html.j2" %}
{% block notification_message %}
{{ recipient.name }}'s custom notification message.
{% endblock %}
Public API documentation
In you GraphQL schema it will expose the following queries, mutations and subscriptions. Please check your GraphiQL playground for better understanding
Queries
query {
me {
notificationsUnreadCount
notifications
}
}
Mutations
mutation {
notificationsMarkAllAsRead(input: { read: true }) {
recipient { notificationsUnreadCount }
}
notificationsMarkAsRead(input: { notificationIds: ["Tm90aWZpY2F0aW9uOjE=", "Tm90aWZpY2F0aW9uOjI="], read: true }) {
recipient { notificationsUnreadCount }
}
}
Subscriptions
subscription {
onNotificationChange {
createdNotification @prependEdge(connections: $connections) {
node {
...NotificationCardFragment
recipient {
id
notificationsUnreadCount
}
}
}
updatedNotification {
...NotificationCardFragment
}
deletedNotificationId @deleteRecord
}
}
How to customize Notification's Model
Create your custom_notifications
django app inside your project and inherit from AbstractNotification
like:
from baseapp_notifications.base import AbstractNotification
class Notification(AbstractNotification):
my_custom_field = models.CharField()
class Meta(AbstractNotification.Meta):
abstract = False
Then make sure to change your settings/base.py
like:
INSTALLED_APPS = [
"baseapp_notifications",
"custom_notifications", # need to have both
]
NOTIFICATIONS_NOTIFICATION_MODEL = "custom_notifications.Notification"
That's it, my_custom_field
should be available in your GraphQL's Notification ObjectType as well.
How to develop
General development instructions can be found in main README.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file baseapp-notifications-0.3.1.tar.gz
.
File metadata
- Download URL: baseapp-notifications-0.3.1.tar.gz
- Upload date:
- Size: 21.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.0 CPython/3.12.4
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 98e50474212a5e1dd1153ffa35fb00ccf2128c16abd013c47d1bc082c3ed93e7 |
|
MD5 | 27f3f9fc3f6f23c5fc5455bdda4f3f04 |
|
BLAKE2b-256 | 08e731f6447471f6d886dcc7c7e3c21ce514108f65c97cd5baa636951270b9b8 |