Welcome | Get started | Dive | Contribute | Topics | Reference | Changes | More

notify: Notification framework

The lino.modlib.notify plugin adds a notification framework to your Lino application.

We assume that you have read the end-user documentation in The notify plugin.

You can play with notifications in the demo projects chatter, noi1e and noi1r. Open two browsers windows (one of them private) and sign in as two different users. Then write a comment in one window and note the desktop notification received by the other user.

Code snippets on this page are tested in the chatter demo project.

Side note: Code snippets (lines starting with >>>) in this document get tested as part of our development workflow. The following initialization snippet tells you which demo project is being used in this document.

>>> import lino
>>> lino.startup('lino_book.projects.chatter.settings')
>>> from lino.api.doctest import *

Concepts

This page will introduce the following new concepts:

notification message

Stored in Message.

push notification

A technology used to implement desktop notifications.

https://rossta.net/blog/using-the-web-push-api-with-vapid.html

push subscription

The fact that a site user has given permission to some of their browsers to show desktop notifications for this site.

Usage

Add lino.modlib.notify to your lino.core.site.Site.get_installed_plugins().

To emit a notification message from your application code, you can

You can use this plugin without enabling desktop notifications. In that case the site users will receive only email notifications and/or dashboard notifications.

How to activate desktop notifications

To enable desktop notifications, there are some requirements:

Set up a public URL for your development server

The Push API requires your web server to be publicly reachable via https. One method to do this for a development server is to use ngrok.

Install ngrok: https://ngrok.com/download

Run ngrok:

$ ngrok http 8000

ngrok by @inconshreveable                                                                                                                                     (Ctrl+C to quit)

Session Status                online
Account                       joe@example.com (Plan: Free)
Version                       2.3.40
Region                        United States (us)
Web Interface                 http://127.0.0.1:4040
Forwarding                    http://b3735559b89b.ngrok.io -> http://localhost:8000
Forwarding                    https://b3735559b89b.ngrok.io -> http://localhost:8000

Connections                   ttl     opn     rt1     rt5     p50     p90
                              268     0       0.00    0.00    0.50    1.39

In most terminals you can then Ctrl-click on the https://b3735559b89b.ngrok.io URL to open your browser on it.

Configure VAPID credentials

See https://github.com/web-push-libs/vapid/tree/main/python

More about the Push API

Push API

A technology for delivering desktop notifications.

Currently a Working Draft published by the W3C Web Applications Working Group, and intended to become a W3C Recommendation.

Unlike alternative technologies like WebSockets or server-sent events, the Push API uses a third-party push server.

Subject and body of a notification message

As an application developer you should understand the different meanings of “subject” and “body”:

  • The body is expected to be a self-sufficient and complete description of the event. If a message has a body, then the subject is not being displayed in the MyMessages summary.

  • The subject might contain limited rich text (text formatting, links) but be aware that this formatting may get lost when the message is sent as an email or as a desktop notification.

Notification messages

You can use Explorer ‣ System ‣ Notification messages to see all notification messages.

>>> # run_menu_command("Explorer --> System --> Notification messages")
>>> rt.show('notify.AllMessages')  
============================ ============================================================== ================ ============= ====== =====================
 Created                      Subject                                                        Recipient        Reply to      seen   sent
---------------------------- -------------------------------------------------------------- ---------------- ------------- ------ ---------------------
 2024-04-06 05:48:00          Broadcast message
 2024-04-06 05:48:00          Welcome on board, Andreas.                                     Andy                                  2024-04-06 05:48:00
 2024-04-06 05:48:00          Welcome on board, Albert.                                      Bert                                  2024-04-06 05:48:00
 2024-04-06 05:48:00          Welcome on board, Chloe.                                       Chloe Cleoment                        2024-04-06 05:48:00
 2024-04-06 05:48:00          Welcome on board, Robin.                                       Robin Rood                            2024-04-06 05:48:00
 ...                          Andy commented on Harry Potter                                 Bert             Comment #7
 ...                          Bert commented on Harry Potter                                 Andy             Comment #8
 ...                          Chloe Cleoment commented on Harry Potter                       Andy             Comment #9
 ...                          Chloe Cleoment commented on Harry Potter                       Bert             Comment #9
 ...                          Robin Rood commented on Harry Potter                           Andy             Comment #10
 ...                          Robin Rood commented on Harry Potter                           Bert             Comment #10
 ...                          Andy commented on Harry Potter                                 Bert             Comment #11
 ...                          Bert commented on Harry Potter                                 Andy             Comment #12
 ...                          Chloe Cleoment commented on Harry Potter                       Andy             Comment #13
 ...                          Chloe Cleoment commented on Harry Potter                       Bert             Comment #13
 ...                          Robin Rood commented on Star Trek                              Chloe Cleoment   Comment #14
 ...                          Andy commented on Star Trek                                    Chloe Cleoment   Comment #15
 ...                          Andy commented on Star Trek                                    Robin Rood       Comment #15
 ...                          Bert commented on Star Trek                                    Chloe Cleoment   Comment #16
 ...                          Bert commented on Star Trek                                    Robin Rood       Comment #16
 ...                          Chloe Cleoment commented on Star Trek                          Robin Rood       Comment #17
 ...                          Robin Rood commented on Star Trek                              Chloe Cleoment   Comment #18
 ...                          Andy commented on Star Trek                                    Chloe Cleoment   Comment #19
 ...                          Andy commented on Star Trek                                    Robin Rood       Comment #19
 ...                          Bert commented on Star Trek                                    Chloe Cleoment   Comment #20
 ...                          Bert commented on Star Trek                                    Robin Rood       Comment #20
 ...                          Chloe Cleoment commented on Hitchhiker's Guide to the Galaxy   Andy             Comment #21
 ...                          Chloe Cleoment commented on Hitchhiker's Guide to the Galaxy   Bert             Comment #21
 ...                          Robin Rood commented on Hitchhiker's Guide to the Galaxy       Andy             Comment #22
 ...                          Robin Rood commented on Hitchhiker's Guide to the Galaxy       Bert             Comment #22
 ...                          Andy commented on Hitchhiker's Guide to the Galaxy             Bert             Comment #23
 ...                          Bert commented on Hitchhiker's Guide to the Galaxy             Andy             Comment #24
 ...                          Chloe Cleoment commented on Hitchhiker's Guide to the Galaxy   Andy             Comment #25
 ...                          Chloe Cleoment commented on Hitchhiker's Guide to the Galaxy   Bert             Comment #25
 ...                          Robin Rood commented on Hitchhiker's Guide to the Galaxy       Andy             Comment #26
 ...                          Robin Rood commented on Hitchhiker's Guide to the Galaxy       Bert             Comment #26
 ...                          Andy commented on Hitchhiker's Guide to the Galaxy             Bert             Comment #27
 ...                          Bert commented on Harry Potter                                 Andy             Comment #28
 ...                          Chloe Cleoment commented on Harry Potter                       Andy             Comment #29
 ...                          Chloe Cleoment commented on Harry Potter                       Bert             Comment #29
 ...                          Robin Rood commented on Harry Potter                           Andy             Comment #30
 ...                          Robin Rood commented on Harry Potter                           Bert             Comment #30
 ...                          Andy commented on Harry Potter                                 Bert             Comment #31
 ...                          Bert commented on Harry Potter                                 Andy             Comment #32
 ...                          Chloe Cleoment commented on Harry Potter                       Andy             Comment #33
 ...                          Chloe Cleoment commented on Harry Potter                       Bert             Comment #33
 ...                          Robin Rood commented on Harry Potter                           Andy             Comment #34
 ...                          Robin Rood commented on Harry Potter                           Bert             Comment #34
 ...                          Andy commented on Star Trek                                    Chloe Cleoment   Comment #35
 ...                          Andy commented on Star Trek                                    Robin Rood       Comment #35
 ...                          Bert commented on Star Trek                                    Chloe Cleoment   Comment #36
 ...                          Bert commented on Star Trek                                    Robin Rood       Comment #36
 ...                          Chloe Cleoment commented on Star Trek                          Robin Rood       Comment #37
 ...                          Robin Rood commented on Star Trek                              Chloe Cleoment   Comment #38
 ...                          Andy commented on Star Trek                                    Chloe Cleoment   Comment #39
 ...                          Andy commented on Star Trek                                    Robin Rood       Comment #39
 ...                          Bert commented on Star Trek                                    Chloe Cleoment   Comment #40
 ...                          Bert commented on Star Trek                                    Robin Rood       Comment #40
 ...                          Chloe Cleoment commented on Star Trek                          Robin Rood       Comment #41
 ...                          Robin Rood commented on Hitchhiker's Guide to the Galaxy       Andy             Comment #42
 ...                          Robin Rood commented on Hitchhiker's Guide to the Galaxy       Bert             Comment #42
 ...                          Andy commented on Hitchhiker's Guide to the Galaxy             Bert             Comment #43
 ...                          Bert commented on Hitchhiker's Guide to the Galaxy             Andy             Comment #44
 ...                          Chloe Cleoment commented on Hitchhiker's Guide to the Galaxy   Andy             Comment #45
 ...                          Chloe Cleoment commented on Hitchhiker's Guide to the Galaxy   Bert             Comment #45
 ...                          Robin Rood commented on Hitchhiker's Guide to the Galaxy       Andy             Comment #46
 ...                          Robin Rood commented on Hitchhiker's Guide to the Galaxy       Bert             Comment #46
 ...                          Andy commented on Hitchhiker's Guide to the Galaxy             Bert             Comment #47
 ...                          Bert commented on Hitchhiker's Guide to the Galaxy             Andy             Comment #48
 ...                          Chloe Cleoment commented on Harry Potter                       Andy             Comment #49
 ...                          Chloe Cleoment commented on Harry Potter                       Bert             Comment #49
 ...                          Robin Rood commented on Harry Potter                           Andy             Comment #50
 ...                          Robin Rood commented on Harry Potter                           Bert             Comment #50
 ...                          Andy commented on Harry Potter                                 Bert             Comment #51
 ...                          Bert commented on Harry Potter                                 Andy             Comment #52
 ...                          Chloe Cleoment commented on Harry Potter                       Andy             Comment #53
 ...                          Chloe Cleoment commented on Harry Potter                       Bert             Comment #53
 ...                          Robin Rood commented on Harry Potter                           Andy             Comment #54
 ...                          Robin Rood commented on Harry Potter                           Bert             Comment #54
============================ ============================================================== ================ ============= ====== =====================

Class reference

class lino.modlib.notify.Message

The Django model that represents a notification message.

subject

The subject of this message. See Subject and body of a notification message.

body

The body of this message. See Subject and body of a notification message.

user

The recipient of this message. The site user to whom this message is to be delivered.

If this is empty, then it is a broadcast notification.

owner

The owner of this message. Expresses what this message is about.

See The owner of a message.

This is a generic foreign key. If this is empty, the message is said to have no owner.

message_type

The notification message type.

reply_to

The comment to which a reply to this message would reply.

An email notification for this message will have this information in its reply-to header.

This is a dummy field unless the lino.modlib.comments plugin is installed.

created

Timestamp of when this message has been emitted.

sent

Timestamp of when this message has been sent via email to its recipient.

seen

Timestamp of when the recipient of this message has marked it as seen.

emit_notification(cls, ar, owner, message_type, msg_func, recipients)

Emit a notification message to each of the given recipients, respecting their individual user settings.

This is a class method that creates zero, one or several database rows.

recipients is an iterable of (user, mail_mode) tuples. Duplicate items, items with user being None and items having mail_mode set to silent are removed.

msg_func is a callable expected to return either None or a tuple (subject, body). It is called for each recipient after having activated the recipient’s language, so that any translatable text will be translated to the user’s language.

The emitting user does not get notified unless they have User.notify_myself is set.

create_message(cls, user, owner=None, **kwargs)

Create a message unless that user has already been notified about that object.

send_summary_emails(cls, mm)

Send summary emails for all pending notifications with the given mail_mode mm.

send_browser_message_for_all_users(self, user)

Send_message to all connected users

send_browser_message(self, user)

Send_message to the user’s browser

class lino.modlib.notify.Messages

Base for all tables of messages.

class lino.modlib.notify.AllMessages(Messages)

The gobal list of all messages.

class lino.modlib.notify.MyMessages(Messages)

Shows messages emitted to me.

Push subscriptions

class lino.modlib.notify.Subscription

The Django model that represents a push subscription.

Loosely inspired by django-webpush.

user
lang
userAgent
endpoint
p256dh
auth

Change notifiers

class lino.modlib.notify.ChangeNotifier

Model mixin for things that emit notifications to a list of observers (or “watchers”) when an instance is modified.

add_change_watcher(self, user)

Parameters:

User:

The user that will be linked to this object as a change watcher.

get_change_subject(self, ar, cw)

Returns the subject text of the notification message to emit.

The default implementation returns a message of style “{user} modified|created {object}” .

Returning None or an empty string means to suppress notification.

get_change_body(self, ar, cw)

Return the body text of the notification message to emit.

The default implementation returns a message “{user} created {what}” or “{user} modified {what}” followed by a summary of the changes.

For tested code snippets see See The get_change_body() method.

get_change_info(self, ar, cw)

Return a list of HTML elements to be inserted into the body.

Removed since 20230822.

This is called by get_change_body(). Subclasses can override this. Usage example lino_xl.lib.notes.models.Note

get_change_owner(self)

Return the owner of the notification to emit.

The “owner” is “the database object we are talking about” and decides who is observing this object.

Notifying actions

A notifying action is an action that pops up a dialog window with at least three fields “Summary”, “Description” and a checkbox “Don’t notify others” to optionally suppress notification.

Screenshot of a notifying action:

../_images/reception.CheckinVisitor.png
class lino.modlib.notify.NotifyingAction

Mixin for notifying actions.

Dialog fields:

notify_subject
notify_body
notify_silent
get_notify_subject(self, ar, obj)

Return the default value of the notify_subject field.

get_notify_body(self, ar, obj)

Return the default value of the notify_body field.

get_notify_owner(self, ar, obj)

Expected to return the owner lino.modlib.notify.Message.owner> of the message.

The default returns None.

ar is the action request, obj the object on which the action is running,

get_notify_recipients(self, ar, obj)

Yield a list of users to be notified.

ar is the action request, obj the object on which the action is running,

A NotifyingAction is a dialog action that potentially sends a notification. It has three dialog fields (“subject”, “body” and a checkbox “silent”). You can have non-dialog actions (or actions with some other dialog than a simple subject and body) which build a custom subject and body and emit a notification. If the emitting object also has a method emit_system_note(), then this is being called as well.

Plugin settings

This plugin adds the following settings, which a server administrator can configure in the settings.py.

notify.remove_after

Automatically remove notification messages after x days.

Default value is 14 days. Set this to None or 0 to deactivate cleanup and keep messages forever.

notify.keep_unseen

Whether to keep unseen messages when removing old messages according to remove_after.

In normal operation this should be True, but e.g. after a flood of messages during experimental phases we might want to get rid of them automatically.

notify.mark_seen_when_sent

When this is True, Lino marks notification messages as seen when they have been sent via email.

notify.use_push_api

Whether to enable desktop notifications using webpush.

In a production server it is mandatory to set your own vapid credentials:

notify.vapid_private_key

The private VAPID key of this site.

notify.vapid_public_key

The public VAPID key of this site.

notify.vapid_admin_email

The VAPID contact address of this site.

>>> from django.conf import settings
>>> from lino.core.utils import is_devserver
>>> # import sys ; sys.argv
>>> is_devserver()
True

Utility functions

lino.modlib.notify.send_pending_emails_often()
lino.modlib.notify.send_pending_emails_daily()
lino.modlib.notify.clear_seen_messages()

Daily task which deletes messages older than remove_after hours.

Choicelists

class lino.modlib.notify.MessageTypes

The list of possible choices for the message_type field of a Message.

class lino.modlib.notify.MailModes

How the system should send email notifications to a user.

silent

Disable notifications for this user.

never

Notify in Lino but never send email.

Actions

class lino.modlib.notify.MarkSeen

Mark this message as seen.

class lino.modlib.notify.MarkAllSeen

Mark all messages as seen.

class lino.modlib.notify.ClearSeen

Mark this message as not yet seen.

Templates used by this plugin

notify/body.eml

A Jinja template used for generating the body of the email when sending a message per email to its recipient.

Available context variables:

  • obj – The Message instance being sent.

  • E – The html namespace etgen.html

  • rt – The runtime API lino.api.rt

  • ar – The action request which caused the message. a BaseRequest instance.

Credits