Code Monkey home page Code Monkey logo

django-webpush's People

Contributors

arogachev avatar ckangnz avatar clearminds avatar dadokkio avatar dartlazer avatar elishowk avatar flimm avatar hmeza avatar jamaalscarlett avatar jialutu avatar jonathanraes avatar mogost avatar neonwarp avatar orsobruno96 avatar privatgt avatar rcmurphy avatar safwanrahman avatar satoon101 avatar skorokithakis avatar totoropy avatar trafitto avatar tyilo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-webpush's Issues

Update on pypi

The repo on PyPi was last updated in 2019. Please update it there to fix issues with Django 4 and allow customisation of subscribe button.

[Chrome Support] [Research] Adding manifest.json

Chrome needs manifest.json to be available in the page while asking for Push notification registration. Otherwise it will throw a error

Uncaught (in promise) DOMException: Registration failed - manifest empty or missing

So for adding support for chrome, we need to add a menifest.json to the directory. An example of menifest.json can be found here. The instruction can be found in MDN

In the menifest.json there is a field for gcm_sender_id. This can be obtained from the google console.
It should be possible for the developer to configure the gcm_sender_id in the settings so that its possible to get it from there.

We should find out a way to get it from settings and generate a json so that it will be possible to load the json in the page with the templatetags

[Chrome Support] Update pywebpush

Recently, pywebpush 0.4.0 is released. Which enable sending notification to chrome broswer. We need to upgrade to pywebpush 0.4.0.
Be mentioned that, as we dont have any test, we just need to test manually if everything works.

change {% webpush_button %}

hi
I am in a situation changing the appearance of webpush_button. I dont want to change webpush package in my project. Is there a way to change it in my template? for example I dont want a button, instead I want a with specific class. How should I do this?

thanks

Get rid of global variables and methods in webpush.js

Currently these variables are in global scope:

var isPushEnabled = false,
  subBtn,
  messageBox,
  registration;

Also these methods: subscribe, unsubscribe, postSubscribeObj.

This is a bad practive especially because their names are common to use. To prevent that we can at least put everything inside window load event handler:

window.addEventListener('load', function() {
    // Place it here
});

Django rest framework: User not found in request

Hi,
I am using using Django Rest Rramework.

I got the package working with all setup in place, The API to save information is called and executed successfully. The only problem right now is that the user information is not saved. My findings say that this is because I am using DRF. The way DRF injects a user into the request is may be different from how the traditional Django does. And hence the request.user in the view of the package in not found.

Right now i am thinking to make a clone of the repo and make changes directly in order to debug and find the exact issue/solution.

Kindly let me know what would be the right way. Or is there is a existing solution to this already.

Thanks

Invalid field name

Hi,

First I want to say thank you for this amazing package!

I am getting this error when trying to subscribe using chrome:

django.core.exceptions.FieldError: Invalid field name(s) for model SubscriptionInfo: 'expirationTime'.

I tried to remove the field 'expirationTime' from the dictionary under views:

`# We at least need the user or group to subscribe for a notification
if request.user.is_authenticated() or group_name:
# Save the subscription info with subscription data
# as the subscription data is a dictionary and its valid
print(subscription_data)
subscription_data.pop('expirationTime')
subscription = subscription_form.get_or_save(subscription_data)
web_push_form.save_or_delete(
subscription=subscription, user=request.user,
status_type=status_type, group_name=group_name)

        # If subscribe is made, means object is created. So return 201
        if status_type == 'subscribe':
            return HttpResponse(status=201)
        # Unsubscribe is made, means object is deleted. So return 202
        elif "unsubscribe":
            return HttpResponse(status=202)`

And it worked but sending notifications to the subscribed browser is not working.
By the way Firefox is working great.

Please help,
Thanks!

"ReferenceError: Notification is not defined" on Firefox when notifications are disabled

If a Firefox user has disabled notifications globally by setting dom.webnotifications.enabled:false in prefs (like me!), there will be no Notification object. webpush.js needs to check whether it exists before trying to test its properties.

See also https://miketaylr.com/posts/2017/02/how-not-to-feature-detect.html which helped me work out the problem after a lot of searching. I had forgotten that I disabled notifications.

Thanks!

Example for sending notification throws error.

TypeError: unhashable type is now thrown when attempting to send
a notifcation.

I am seeing the error attempt to send a notification using the following code:

from webpush import models, utils
sub = subscription=models.SubscriptionInfo.objects.get(browser='chrome')
push = models.PushInformation.objects.get(subscription=sub); utils._send_notification(push, {"header": "what", "body": "up"}, 100)

error:

Traceback (most recent call last):
File "", line 1, in 
File "/home/jscarlett/venv/adm/local/lib/python2.7/site-packages/webpush/utils.py", line 30, in send_notification
req = WebPusher(subscription_data).send(data=payload, ttl=ttl, gcm_key=gcm_key)
File "/home/jscarlett/venv/adm/local/lib/python2.7/site-packages/pywebpush/__init_.py", line 175, in send
encoded = self.encode(data)
File "/home/jscarlett/venv/adm/local/lib/python2.7/site-packages/pywebpush/init.py", line 147, in encode
authSecret=self.auth_key)
File "/home/jscarlett/venv/adm/local/lib/python2.7/site-packages/http_ece/init.py", line 152, in encrypt
result += encryptRecord(key_, nonce_, counter, buffer[i:i+rs])
TypeError: unhashable type

I was able to fix it by adding this check to the encode method of pywebpush: https://gist.github.com/jamaalscarlett/b791886a206b0fb3ad1c348877298509#file-__init__-py-L23
but I think the validation should probably be done in this library.

Allow translations in subscribing UI

Currently all informing messages for user are hardcoded as js strings, for example:

messageBox.textContent = 'Service Worker is not supported in your Browser!';

Translation to different language requires copying whole js and translating these strings.

Clicking on the notification should act

So currently, clicking on the notification do nothing. So it can be only used to show notification. Not possible to send a notification that user can click on the notification and they will be redirect to any link.
So we should implement that the sender can configure a url to which the receiver will be taken while he clicks on the notification.

So it will work like following:

  • The sender will configure a url while sending notification. The url will be passed to the user's browser with payload.
  • In the user browser it will parse the payload and get the url
  • A event listener should be added to the notification
  • When the user click on the event listener, he should be taken to the url as the sender provided

So it needs some backend work and most of the javascript work.

Subscribing button - allow not only text

Button can be for example simple icon without any text with bell changing to icon with crossed "X" for unsubscribing.

Or like in my case it can contain both icon and text (I use Bootstrap 3 Glyphicons):

<button class="btn btn-default" id="webpush-subscribe-button" {% if group %}data-group="{{ group }}"{% endif %} data-url="{{ url }}">
    <span class="glyphicon glyphicon-bell"></span> Подписаться
</button>

Then using:

subBtn.textContent = 'Subscribe to Push Messaging';

is not acceptable.

For my case I used this method:

function changeSubBtnText(subscribe) {
    if (subscribe === undefined) {
        subscribe = true;
    }

    var text = subscribe ? 'Подписаться' : 'Отписаться';
    subBtn.innerHTML = '<span class="glyphicon glyphicon-bell"></span> ' + text;
}

and then I call changeSubBtnText() for subscribing state and changeSubBtnText(false) for unsubscribing state.

Better way to store webpush data in DOM

In webpush.html template used by {% webpush %} template tag there is div element storing some webpush related data:

<div id="webpush-data" {% if group %} data-group="{{ group }}" {% endif %} data-url="{{ url }}" hidden></div>

1) If this tag will be included in head section (and README says to add it there), then to have div inside HTML head tag will be semantically incorrect. Mozilla recognizes that and automatically moves it to body section during page loading. One more disadvantage is you can't register any scripts after {% webpush %}. For example, I can't write that:

<head>
    {% webpush %}
    <script src="{% static 'core/js/custom.js' %}"></script>
</head>

custom.js will be ignored and not loaded at all.

2) It's incorrect to mix script declarations and elements storing data in one place. Also this element is tightly coupled and used with {% webpush_button %} tag, why not place it there? This is more appropriate place.

3) Having a div for only storing value from server probably is not the best choice. Hidden input with data attributes will be enough, but if we use it in {% webpush_button %}, why not use existing elements for that such as button itself?

Version 0.3.0 requires pywebpush 1.6.0 but the code uses more recent features

The current release (version 0.3.0) requires pywebpush 1.6.0.

When sending a notification, exceptions of type WebPushException are caught and their response field is investigated

if e.response.status_code == 410:

However, this field was added later in pywebpush.

Consequence: sending a notification to non-existent endpoint triggers a crash.

pywebpush should be updated.

KeyError: 'endpoint' when using admin interface to send notification

Hi, I have installed the package and generated the needed keys. I subscribed myself to receive notifications with an account without issues up till then.

When I log to the django admin interface and try to send a message to test if it works I get the following error.

File "/home/socialapp/deepmetricsapps/NuevocentroShopping/lib/python3.5/site-packages/webpush/utils.py", line 71, in _process_subscription_info endpoint = subscription_data.pop("endpoint") KeyError: 'endpoint'

Is this package still working? or am I doing something wrong?
I am using Django 2.0+ with gunicorn and nginx as reverse proxy. I subscribed to the service using chrome 70+

endpoint length in Microsoft Edge

current endpoint URLField max length is 255. However, Microsoft is using endpoints with more than 400 characters.

Could you update it to be 500 characters?

Thank you

Request body in save_info view is bytes object

During subscribing I get this error:

TypeError: the JSON object must be str, not 'bytes'

This is because of this line in save_info view:

post_data = json.loads(request.body)

After debugging I have found that request.body is bytes object, not simple string.

To fix that we need to convert it to string:

post_data = json.loads(request.body.decode(encoding='utf-8'))

However I'm not sure, maybe it can be both string and bytes depending on different circumstances.

In this case we can explicitly check for a type before converting.

request_body = request.body
if isinstance(request_body, bytes):
    request_body = request_body.decode(encoding='utf-8')
post_data = json.loads(request.body)

But it would be better to find the reason why request.body can be a bytes object.

Some details: I use Python 3.5.2 and Django 1.9.5 in my project. Error happens in both Mozilla Firefox 49.0.1 and Chrome 53.0.2785.143 m browsers (these are the latest versions at the moment).

I tested it with the latest extension's code.

As a current workaround I overrided save_info view and applied this fix and also overrided save_webpush_info url, pointed it to custom view and placed it above extensions's urls:

url(r'^webpush/', include('webpush.urls')),

Subscribing - consider existing subscription

When page initially loaded, subscribe button is shown regardless of user already subscribed or not, This is not user friendly interface.

At least we need to check if user already subscribed and show some information about that (for example display "Unsubscribe" button instead).

Use a local ip address instead of a ngrok?

Use a local ip address instead of a ngrok?
Hi thanks for the great work.

Can I dispense with ngrok?
I was asking how I could run the service via a local IP address
Eg on an internal network

router 10.10.1.1
// me : https://10.10.1.2
//pc2: 10.10.1.3

I want to communicate this way
iam use https from django ssl
but not working
thanks.

TypeError: WebPushException does not take keyword arguments

You can't pass extra= anything when raising WebPushException.

In django-webpush utils.py:

utils.py:22:raise WebPushException("Push failed.", extra=errors)
utils.py:40:raise WebPushException("Push failed.", extra=errors)

but in pywebpush init.py:

class WebPushException(Exception):
    pass

Questions: is possible send notification when save models in admin interface

Hi, it is possible to send a notification when I save a new record in my model, I use the django admin, I have tried to use signal to send the notification but it returns the following error!
WebPushException () takes no keyword arguments.
send me the notification but it takes and throws the error
example code: i have models name News
@receiver(post_save, sender=News)
def send_new_message_notification(sender, created, **kwargs):
message = kwargs['instance']
if created:
try:
obj = User.objects.get(pk=message.author.pk)
except sender.DoesNotExist:
pass
payload = {"head": "Welcome!", "body": message.title}
send_user_notification(user=obj, payload=payload, ttl=1000)

any help i will appreciate it
thank

403 Google

I used the Fix from chris54
But now i got a 403 from Google
WebPushException at /admin/webpush/pushinformation/
I try to use the admin comand "Send test message"

send_notification - public method

There is missing a public method to send a notification to a single subcription.

Why it is needed?

  • a user wants to send notification 3x times a day
    • morning to phone
    • afternoon to desktop
    • evening to tablet

Another problem with sending a notification to all user devices is when sending failed the loop is interrupted. That's why I would like to have better control over the process.

  • a single subscription
  • queryset of subscriptions

Auto Subscription

How to subscribe every user automatically without clicking the subscribe button and need to disable the button

[Tracker] Adding Support For Chrome

So Chrome uses a different approach for getting user permission. Also, some different configuration is needed for sending push notification to android device. Need to find out that and open new issues about each task

SubscriptionForm invalid due to missing fields p256dh and auth.

When I click on subscribe button, server response is 400 due to missing 'p256dh' and 'auth' values(SubscriptionInfo table).

subscription_form.errors
>> {'p256dh': [u'This field is required.'], 'auth': [u'This field is required.']}

Where should i provide values for these fields ?

JS files should be loaded from main app static/js

Both JS files:
serviceworker.js
webpush.js

should be loaded from main app static/js rather then django_webpush app,
because they need to be customized.

A user can include them like jquery file or so. (just extend readme.md)

UnicodeEncodeError: 'ascii' codec can't encode character u'\u2019'

Hi,

When I call the below lines in my applications, I got the ASCII encode error.
send_user_notification(user=user, payload=payload, ttl=1000)
Below I have attached the Screenshot for the issue and payload parameters. Can you help with this?

Payload Parameters:
image

Ascii encode error:

image

Init error on django 1.9.7

I am having errors to runserver on django 1.9.7:

"INSTALLED_APPS." % (module, name)
RuntimeError: Model class django.contrib.contenttypes.models.ContentType doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.
Performing system checks...

It seems that django version doesn't play well with import on init.py. Once I move the functions to utils.py everything seems fine.

how to log payload onmessage

i've tried below code to print the payload data but not working


if('serviceWorker' in navigator){
   
   navigator.serviceWorker.addEventListener('message', function(event) {
    consloe.log(event.data);
  });

}

Not working...

I try follow all steps in read.me but nothing not working.

  1. added installed_apps
  2. added urlpatterns
  3. manage.py migrate
  4. get WEBPUSH_SETTINGS = { "VAPID_PUBLIC_KEY": "xxx", "VAPID_PRIVATE_KEY": "xxx", "VAPID_ADMIN_EMAIL": "[email protected]"
    } from this link https://web-push-codelab.glitch.me
  5. try to use it:
    image
  6. nothing in my browser...

So, what i need to do this work?

Trying to load models in __init__ fails in 1.10

Django 1.10 fails with an "Apps are not ready" error when trying to load webpush because it's trying to load its models in __init__.py but models haven't been loaded yet. The project should probably be restructured so it either uses lazy loading or doesn't load anything in __init__.py.

Adding Test

Need to add test for everything so we dont get regression in future. also make it run into any CI

Consider an option to have only basic functionality in js and not force user to use specific UI

As I said in #16 in this comment maybe it will be better to have just basic functionality in JS and not force user to use specific UI because it's hard to cover all possible variations and nuances.

In this case user can build his own interface, but for subscribing / unsubscribing he just only needs to call one method. Also we can generate some events and changes in UI will be done by subscribing to these events. This way logic and presentation will become more separated from each other.

We still can have basic template with button and probably it will fit majority of users, but it can be easily overridden using Django template mechanism.

Not receiving test message

Hello, in the admin i can see all the PushInformations object been created, some with users and other without which i assume this is working ok. The Send test message action when executed returns a Test sent successfully, which is also ok, but no notification is receive.
I have checked that the route https://[domain]/webpush/webpush_serviceworker.js exists.
Not sure where else i have to look to get my notification working.
thanks

manifest.json conflict

Site can already contain manifest.json file. For example if you use favicon generator it can be like this:

{
    "name": "Project name",
    "icons": [
        {
            "src": "\/static\/core\/images\/favicons\/android-chrome-36x36.png",
            "sizes": "36x36",
            "type": "image\/png",
            "density": 0.75
        },
        {
            "src": "\/static\/core\/images\/favicons\/android-chrome-48x48.png",
            "sizes": "48x48",
            "type": "image\/png",
            "density": 1
        },
        {
            "src": "\/static\/core\/images\/favicons\/android-chrome-72x72.png",
            "sizes": "72x72",
            "type": "image\/png",
            "density": 1.5
        },
        {
            "src": "\/static\/core\/images\/favicons\/android-chrome-96x96.png",
            "sizes": "96x96",
            "type": "image\/png",
            "density": 2
        },
        {
            "src": "\/static\/core\/images\/favicons\/android-chrome-144x144.png",
            "sizes": "144x144",
            "type": "image\/png",
            "density": 3
        },
        {
            "src": "\/static\/core\/images\/favicons\/android-chrome-192x192.png",
            "sizes": "192x192",
            "type": "image\/png",
            "density": 4
        }
    ]
}

And it's already included in head section in layout template along with other favicons related images:

<link rel="apple-touch-icon" sizes="57x57" href="{% static 'core/images/favicons/apple-touch-icon-57x57.png' %}">
<link rel="apple-touch-icon" sizes="60x60" href="{% static 'core/images/favicons/apple-touch-icon-60x60.png' %}">
<link rel="apple-touch-icon" sizes="72x72" href="{% static 'core/images/favicons/apple-touch-icon-72x72.png' %}">
<link rel="apple-touch-icon" sizes="76x76" href="{% static 'core/images/favicons/apple-touch-icon-76x76.png' %}">
<link rel="apple-touch-icon" sizes="114x114" href="{% static 'core/images/favicons/apple-touch-icon-114x114.png' %}">
<link rel="apple-touch-icon" sizes="120x120" href="{% static 'core/images/favicons/apple-touch-icon-120x120.png' %}">
<link rel="apple-touch-icon" sizes="144x144" href="{% static 'core/images/favicons/apple-touch-icon-144x144.png' %}">
<link rel="apple-touch-icon" sizes="152x152" href="{% static 'core/images/favicons/apple-touch-icon-152x152.png' %}">
<link rel="apple-touch-icon" sizes="180x180" href="{% static 'core/images/favicons/apple-touch-icon-180x180.png' %}">
<link rel="icon" type="image/png" href="{% static 'core/images/favicons/favicon-32x32.png' %}" sizes="32x32">
<link rel="icon" type="image/png" href="{% static 'core/images/favicons/android-chrome-192x192.png' %}" sizes="192x192">
<link rel="icon" type="image/png" href="{% static 'core/images/favicons/favicon-96x96.png' %}" sizes="96x96">
<link rel="icon" type="image/png" href="{% static 'core/images/favicons/favicon-16x16.png' %}" sizes="16x16">
<!-- Manifest declaration begin -->
<link rel="manifest" href="{% static 'core/images/favicons/manifest.json' %}">
<!-- Manifest declaration end -->
<link rel="mask-icon" href="{% static 'core/images/favicons/safari-pinned-tab.svg' %}" color="#5bbad5">
<link rel="shortcut icon" href="{% static 'core/images/favicons/favicon.ico' %}">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="msapplication-TileImage" content="{% static 'core/images/favicons/mstile-144x144.png' %}">
<meta name="msapplication-config" content="{% static 'core/images/favicons/browserconfig.xml' %}">
<meta name="theme-color" content="#ffffff">

If I include {% webpush %} after favicons, it's ignored and I get the error about missing gcm_sender_id which is needed for Chrome. If I placed it above favicons section - it works, but seems like only first manifest is loaded (site / app can have only one manifest.json), further declarations are ignored so favicons will not work correctly.

Probably the order in template doesn't always matter (the order of loading by browser does), but anyways two manifest.json declarations can cause conflict.

As a current workaround, I overrided webpush.html template, removed manifest declaration from there and added gcm_sender_id to existing manifest.json.

I think we need an option to use existing manifest.json instead of creating new one.

Group sending is not clear

Ive found that you have a Group table which can be appended to with a group name. However there is no post method or view for adding a group. Sure it can be done manually. Also, if we have two entries one for a user who is authenticated and the same user being in a group. The send_group_notification sends two notifications. One for the specific user and another for the group which also goes to the same user. This is not correct as you would only want one notification to be sent. This is happening here in save_info method of webpush views.py

    if request.user.is_authenticated or group_name:
        # Save the subscription info with subscription data
        # as the subscription data is a dictionary and its valid
        subscription = subscription_form.get_or_save()
        web_push_form.save_or_delete(
            subscription=subscription, **user=request.user,**
            status_type=status_type, group_name=group_name)

As both group and user information is sent while it should be exclusive one or the other.
The documentation for group creation is sparse and not clear.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.