Browse Source

Jun 21 [UPDT] Updated 'mail_push_notification'

pull/331/head
AjmalCybro 10 months ago
parent
commit
351e85acb2
  1. 2
      mail_push_notification/README.rst
  2. 8
      mail_push_notification/__manifest__.py
  3. 5
      mail_push_notification/doc/RELEASE_NOTES.md
  4. 1
      mail_push_notification/models/__init__.py
  5. 93
      mail_push_notification/models/mail_thread.py
  6. 22
      mail_push_notification/models/res_company.py
  7. 91
      mail_push_notification/models/res_config_settings.py
  8. 29
      mail_push_notification/models/res_users.py
  9. BIN
      mail_push_notification/static/description/assets/screenshots/12.png
  10. BIN
      mail_push_notification/static/description/assets/screenshots/13.png
  11. BIN
      mail_push_notification/static/description/assets/screenshots/14.png
  12. BIN
      mail_push_notification/static/description/assets/screenshots/15.png
  13. BIN
      mail_push_notification/static/description/assets/screenshots/17.png
  14. BIN
      mail_push_notification/static/description/assets/screenshots/2.png
  15. BIN
      mail_push_notification/static/description/assets/screenshots/22.png
  16. 43
      mail_push_notification/static/description/index.html
  17. 124
      mail_push_notification/static/src/js/firebase.js
  18. 55
      mail_push_notification/views/res_config_settings_views.xml

2
mail_push_notification/README.rst

@ -8,7 +8,7 @@ Push Notification From ChatBox
Configuration Configuration
============= =============
* Install the pyfcm python package * Install the firebase_admin python package
* Install our module and make sure that your instance served over https.Firebase is intent on being a highly secure solution, so they have chosen to require the use of a https for all communication and http is not working. * Install our module and make sure that your instance served over https.Firebase is intent on being a highly secure solution, so they have chosen to require the use of a https for all communication and http is not working.
* After installation of module its important that allow the notification access in the webpage * After installation of module its important that allow the notification access in the webpage

8
mail_push_notification/__manifest__.py

@ -21,10 +21,10 @@
############################################################################# #############################################################################
{ {
"name": "Push Notification From ChatBox", "name": "Push Notification From ChatBox",
'version': '17.0.1.0.0', 'version': '17.0.2.0.0',
'category': 'Discuss,Extra Tools', 'category': 'Discuss,Extra Tools',
'summary': 'With Push Notification From ChatBox, users can respond promptly' 'summary': """With Push Notification From ChatBox, users can respond
' to important messages, improving communication efficiency.', promptly to important messages, improving communication efficiency.""",
'description': 'Push Notification From ChatBox is valuable for teams ' 'description': 'Push Notification From ChatBox is valuable for teams '
'looking to streamline communication and enhance ' 'looking to streamline communication and enhance '
'productivity within the Odoo platform.', 'productivity within the Odoo platform.',
@ -44,7 +44,7 @@
"mail_push_notification/static/src/js/firebase.js", "mail_push_notification/static/src/js/firebase.js",
], ],
}, },
"external_dependencies": {"python": ["pyfcm"]}, "external_dependencies": {"python": ["firebase_admin"]},
'images': ['static/description/banner.jpg'], 'images': ['static/description/banner.jpg'],
'license': 'LGPL-3', 'license': 'LGPL-3',
'installable': True, 'installable': True,

5
mail_push_notification/doc/RELEASE_NOTES.md

@ -4,3 +4,8 @@
#### Version 17.0.1.0.0 #### Version 17.0.1.0.0
#### ADD #### ADD
- Initial commit for Push Notification From ChatBox - Initial commit for Push Notification From ChatBox
#### 01.06.2024
#### Version 17.0.2.0.0
#### UPDT
- Migrated from legacy FCM APIs to HTTP v1

1
mail_push_notification/models/__init__.py

@ -23,3 +23,4 @@ from . import mail_thread
from . import push_notification from . import push_notification
from . import res_company from . import res_company
from . import res_config_settings from . import res_config_settings
from . import res_users

93
mail_push_notification/models/mail_thread.py

@ -19,7 +19,7 @@
# If not, see <http://www.gnu.org/licenses/>. # If not, see <http://www.gnu.org/licenses/>.
# #
############################################################################# #############################################################################
from pyfcm import FCMNotification from firebase_admin import messaging, initialize_app, credentials, _apps
from odoo import models from odoo import models
@ -28,39 +28,74 @@ class MailThread(models.AbstractModel):
_inherit = 'mail.thread' _inherit = 'mail.thread'
def _notify_thread(self, message, msg_vals=False, **kwargs): def _notify_thread(self, message, msg_vals=False, **kwargs):
"""Supering the _notify_thread() function to fetch the details of the """Override the _notify_thread() function to fetch chat message details
chat message and push that message as a notification """ and push that message as a notification."""
res = super(MailThread, self)._notify_thread(message, res = super()._notify_thread(message, msg_vals=msg_vals, **kwargs)
msg_vals=msg_vals,
**kwargs)
msg = message.read() msg = message.read()
if self.env.company.push_notification and self.env.user.has_group( if (self.env.company.push_notification and
'base.group_user'): self.env.user.has_group('base.group_user')):
try: try:
push_service = FCMNotification(
api_key=self.env.company.server_key)
receiver_id = False
domain = [] domain = []
receiver_ids = self._get_receiver_ids(msg)
user_list = [rec.id for rec in receiver_ids]
if receiver_ids:
domain = [('user_id', 'in', user_list)]
self._send_push_notification(msg, domain)
except Exception as e:
self.env['ir.logging'].sudo().create({
'name': 'Push Notification Error',
'type': 'server',
'level': 'ERROR',
'message': str(e),
'path': 'mail.thread',
'func': '_notify_thread',
'line': '45',
})
return res
def _get_receiver_ids(self, msg):
"""Identify the receiver of the notification."""
receiver_ids = []
receiver_id = False
if self.channel_type != 'channel': if self.channel_type != 'channel':
for partner in self.channel_partner_ids: for partner in self.channel_partner_ids:
if partner.id != msg[0]['author_id'][0]: if partner.id != msg[0]['author_id'][0]:
receiver_id = self.env['res.users'].search([( receiver_id = self.env['res.users'].search(
'partner_id', [('partner_id', '=', partner.id)])
'=',
partner.id)])
if receiver_id: if receiver_id:
domain = [('user_id', '=', receiver_ids.append(receiver_id)
receiver_id.id)] else:
push_service.notify_multiple_devices( for partner in self.channel_partner_ids:
registration_ids=[registration_id.register_id for receiver_id = self.env['res.users'].search(
registration_id in [('partner_id', '=', partner.id)])
self.env['push.notification'].search( if receiver_id:
domain)], receiver_ids.append(receiver_id)
message_title='Send by ' + msg[0]['author_id'][1], return receiver_ids
message_body=msg[0]['description'],
extra_notification_kwargs={ def _send_push_notification(self, msg, domain):
'click_action': '/web' """Send a push notification using Firebase."""
if not _apps:
cred = credentials.Certificate({
"type": "service_account",
"project_id": self.env.company.project_id_firebase,
"private_key_id": self.env.company.private_key_ref,
"private_key": self.env.company.private_key.replace('\\n',
'\n'),
"client_email": self.env.company.client_email,
"client_id": self.env.company.client_id_firebase,
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": self.env.company.client_cert_url,
"universe_domain": "googleapis.com"
}) })
except Exception: initialize_app(cred)
pass message = messaging.MulticastMessage(
return res notification=messaging.Notification(
title='Message from ' + msg[0]['author_id'][1],
body=msg[0]['body']
),
tokens=[reg_id.register_id for reg_id in
self.env['push.notification'].search(domain)]
)
messaging.send_each_for_multicast(message)

22
mail_push_notification/models/res_company.py

@ -29,8 +29,23 @@ class ResCompany(models.Model):
push_notification = fields.Boolean(string='Enable Push Notification', push_notification = fields.Boolean(string='Enable Push Notification',
help="Enable Web Push Notification") help="Enable Web Push Notification")
server_key = fields.Char(string="Server Key", private_key_ref = fields.Char(string='Private Key Id',
help="Server Key of the firebase") help="Private Key Id in the certificate")
project_id_firebase = fields.Char(string="Project Id",
help='Corresponding projectId of '
'firebase config')
private_key = fields.Char(string="Private Key",
help="Private Key value in the firebase "
"certificate"
)
client_email = fields.Char(string="Client Email",
help='Client Email in the firebase config')
client_id_firebase = fields.Char(string="Client Id",
help='Client Id in the firebase config')
client_cert_url = fields.Char(string="Client Certificate Url",
help='Value corresponding to '
'client_x509_cert_url in the '
'firebase config')
vapid = fields.Char(string="Vapid", help='VapId of the firebase', vapid = fields.Char(string="Vapid", help='VapId of the firebase',
readonly=False) readonly=False)
api_key = fields.Char(string="Api Key", api_key = fields.Char(string="Api Key",
@ -39,9 +54,6 @@ class ResCompany(models.Model):
auth_domain = fields.Char(string="Auth Domain", auth_domain = fields.Char(string="Auth Domain",
help='Corresponding authDomain of firebase ' help='Corresponding authDomain of firebase '
'config') 'config')
project_id_firebase = fields.Char(string="Project Id",
help='Corresponding projectId of '
'firebase config')
storage_bucket = fields.Char(string="Storage Bucket", storage_bucket = fields.Char(string="Storage Bucket",
help='Corresponding storageBucket of ' help='Corresponding storageBucket of '
'firebase config') 'firebase config')

91
mail_push_notification/models/res_config_settings.py

@ -19,7 +19,8 @@
# If not, see <http://www.gnu.org/licenses/>. # If not, see <http://www.gnu.org/licenses/>.
# #
############################################################################# #############################################################################
from pyfcm import FCMNotification from firebase_admin import initialize_app, _apps
from firebase_admin import credentials
from odoo import fields, models, _ from odoo import fields, models, _
@ -32,11 +33,33 @@ class ResConfigSettings(models.TransientModel):
help="Enable Web Push Notification", help="Enable Web Push Notification",
related='company_id.push_notification', related='company_id.push_notification',
readonly=False) readonly=False)
server_key = fields.Char(string="Server Key", project_id_firebase = fields.Char(string="Project Id",
help="Server Key of the firebase", help='Corresponding projectId of '
related='company_id.server_key', readonly=False) 'firebase config',
vapid = fields.Char(string="Vapid", help='VapId of the firebase', related='company_id.project_id_firebase',
related='company_id.vapid', readonly=False) readonly=False)
private_key_ref = fields.Char(string='Private Key Id',
help="Private Key Id in the certificate",
related='company_id.private_key_ref',
readonly=False)
private_key = fields.Char(string="Private Key",
help="Private Key value in the firebase "
"certificate",
related='company_id.private_key', readonly=False)
client_email = fields.Char(string="Client Email", help='Client Email in '
'the firebase config',
related='company_id.client_email',
readonly=False)
client_id_firebase = fields.Char(string="Client Id",
help='Client Id in the firebase config',
related='company_id.client_id_firebase',
readonly=False)
client_cert_url = fields.Char(string="Client Certificate Url",
help='Value corresponding to '
'client_x509_cert_url in the firebase '
'config',
related='company_id.client_cert_url',
readonly=False)
api_key = fields.Char(string="Api Key", api_key = fields.Char(string="Api Key",
help='Corresponding apiKey of firebase config', help='Corresponding apiKey of firebase config',
related='company_id.api_key', readonly=False) related='company_id.api_key', readonly=False)
@ -44,11 +67,7 @@ class ResConfigSettings(models.TransientModel):
help='Corresponding authDomain of firebase ' help='Corresponding authDomain of firebase '
'config', 'config',
related='company_id.auth_domain', readonly=False) related='company_id.auth_domain', readonly=False)
project_id_firebase = fields.Char(string="Project Id",
help='Corresponding projectId of '
'firebase config',
related='company_id.project_id_firebase',
readonly=False)
storage_bucket = fields.Char(string="Storage Bucket", storage_bucket = fields.Char(string="Storage Bucket",
help='Corresponding storageBucket of ' help='Corresponding storageBucket of '
'firebase config', 'firebase config',
@ -58,8 +77,7 @@ class ResConfigSettings(models.TransientModel):
help='Corresponding ' help='Corresponding '
'messagingSenderId of ' 'messagingSenderId of '
'firebase config', 'firebase config',
related='company_id' related='company_id.messaging_sender_id_firebase',
'.messaging_sender_id_firebase',
readonly=False) readonly=False)
app_id_firebase = fields.Char(string="App Id", app_id_firebase = fields.Char(string="App Id",
help='Corresponding appId of firebase config', help='Corresponding appId of firebase config',
@ -71,46 +89,47 @@ class ResConfigSettings(models.TransientModel):
related='company_id' related='company_id'
'.measurement_id_firebase', '.measurement_id_firebase',
readonly=False) readonly=False)
vapid = fields.Char(string="Vapid", help='VapId of the firebase',
related='company_id.vapid', readonly=False)
def test_connection(self): def test_connection(self):
"""Test connection to firebase using the firebase credentials""" """Test connection to firebase using the firebase credentials"""
if self.env.company.push_notification: if not self.env.company.push_notification:
return False
try: try:
push_service = FCMNotification( # Initialize the firebase app with the credentials
api_key=self.env.company.server_key) if not _apps:
registration_ids = self.env['push.notification'].sudo().search( cred = credentials.Certificate(
[('user_id', '=', self.env.user.id)]) {
push_service.notify_multiple_devices( "type": "service_account",
registration_ids=[registration_id.register_id for "project_id": self.project_id_firebase,
registration_id in registration_ids], "private_key_id": self.private_key_ref,
message_title='Test Connection', "private_key": self.private_key.replace('\\n', '\n'),
message_body='Successfully', "client_email": self.client_email,
extra_notification_kwargs={ "client_id": self.client_id_firebase,
'click_action': '/web' "auth_uri": "https://accounts.google.com/o/oauth2/auth",
}) "token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": self.client_cert_url,
"universe_domain": "googleapis.com"
}
)
initialize_app(cred)
return { return {
'type': 'ir.actions.client', 'type': 'ir.actions.client',
'tag': 'display_notification', 'tag': 'display_notification',
'params': { 'params': {
'type': 'success', 'type': 'success',
'message': _("Connection successfully established"), 'message': _("Connection successfully established"),
'next': {
'type': 'ir.actions.client',
'tag': 'reload_context',
},
} }
} }
except: except Exception as e:
return { return {
'type': 'ir.actions.client', 'type': 'ir.actions.client',
'tag': 'display_notification', 'tag': 'display_notification',
'params': { 'params': {
'type': 'danger', 'type': 'danger',
'message': _( 'message': _(
"Failed to connect with firebase"), "Failed to connect with firebase:%s" % e),
'next': {
'type': 'ir.actions.client',
'tag': 'reload_context',
},
} }
} }

29
mail_push_notification/models/res_users.py

@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Gokul PI (<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import models
class ResUsers(models.Model):
_inherit = 'res.users'
def has_push_notification_permission(self):
return self.has_group('base.group_user')

BIN
mail_push_notification/static/description/assets/screenshots/12.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

After

Width:  |  Height:  |  Size: 118 KiB

BIN
mail_push_notification/static/description/assets/screenshots/13.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 KiB

After

Width:  |  Height:  |  Size: 127 KiB

BIN
mail_push_notification/static/description/assets/screenshots/14.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

After

Width:  |  Height:  |  Size: 126 KiB

BIN
mail_push_notification/static/description/assets/screenshots/15.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

After

Width:  |  Height:  |  Size: 196 KiB

BIN
mail_push_notification/static/description/assets/screenshots/17.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 69 KiB

BIN
mail_push_notification/static/description/assets/screenshots/2.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 KiB

After

Width:  |  Height:  |  Size: 217 KiB

BIN
mail_push_notification/static/description/assets/screenshots/22.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 72 KiB

43
mail_push_notification/static/description/index.html

@ -378,8 +378,8 @@
<div class="px-3"> <div class="px-3">
<h4 class="mt-2" <h4 class="mt-2"
style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important"> style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important">
You can see the credentials(not server key You can see the credentials(apiKey, authDomain, projectId, storageBucket,
and vapid) we need in odoo in the General messagingSenderId, appId, measurementId) in the General
--> Your apps --> Your apps
</h4> </h4>
</div> </div>
@ -408,11 +408,8 @@
<div class="px-3"> <div class="px-3">
<h4 class="mt-2" <h4 class="mt-2"
style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important"> style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important">
You can create the server key we need in Now we need to create a Vapid goto the Cloud Messaging --> Web configuration -->
odoo.For that goto the Cloud Messaging --> Generate Key pair
Cloud Messaging API (Legacy) --> 3 dots
-->Manage API in Google Cloud Console -->
Enable the Cloud Messaging
</h4> </h4>
</div> </div>
</div> </div>
@ -426,22 +423,10 @@
class="img-responsive" width="100%" class="img-responsive" width="100%"
height="auto"> height="auto">
</div> </div>
</div>
</div>
<div class="col-lg-12 py-2"
style="padding: 1rem 4rem !important;">
<div
style="border: 1px solid #d8d6d6; border-radius: 4px; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);">
<div class="row justify-content-center p-3 w-100 m-0">
<img src="assets/screenshots/14.png"
class="img-responsive" width="100%"
height="auto">
</div>
<div class="px-3"> <div class="px-3">
<h4 class="mt-2" <h4 class="mt-2"
style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important"> style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important">
After that you can see the Server key in Cloud We can see the Vapid here.
Messaging API (Legacy)
</h4> </h4>
</div> </div>
</div> </div>
@ -451,16 +436,16 @@
<div <div
style="border: 1px solid #d8d6d6; border-radius: 4px; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> style="border: 1px solid #d8d6d6; border-radius: 4px; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);">
<div class="row justify-content-center p-3 w-100 m-0"> <div class="row justify-content-center p-3 w-100 m-0">
<img src="assets/screenshots/15.png" <img src="assets/screenshots/14.png"
class="img-responsive" width="100%" class="img-responsive" width="100%"
height="auto"> height="auto">
</div> </div>
<div class="px-3"> <div class="px-3">
<h4 class="mt-2" <h4 class="mt-2"
style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important"> style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important">
Now we need to create a Vapid goto the Cloud After that navigate to Firebase Admin SDK under Service accounts, select Python and
Messaging --> Web configuration --> Generate Generate new private key. It will generate a json file containing all remaining
Key pair credentials.
</h4> </h4>
</div> </div>
</div> </div>
@ -470,15 +455,14 @@
<div <div
style="border: 1px solid #d8d6d6; border-radius: 4px; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> style="border: 1px solid #d8d6d6; border-radius: 4px; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);">
<div class="row justify-content-center p-3 w-100 m-0"> <div class="row justify-content-center p-3 w-100 m-0">
<img src="assets/screenshots/16.png" <img src="assets/screenshots/15.png"
class="img-responsive" width="100%" class="img-responsive" width="100%"
height="auto"> height="auto">
</div> </div>
<div class="px-3"> <div class="px-3">
<h4 class="mt-2" <h4 class="mt-2"
style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important"> style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important">
After that you can see the public key of the Downloaded json file.
Vap id Cloud Messaging --> Web configuration
</h4> </h4>
</div> </div>
</div> </div>
@ -495,9 +479,8 @@
<div class="px-3"> <div class="px-3">
<h4 class="mt-2" <h4 class="mt-2"
style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important"> style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important">
Goto the General Settings --> Firebase Push Goto the General Settings --> Firebase Push Notification --> enable the 'Enable Push
Notification --> enable the 'Enable Push Notification' then you can set the credentials.
Notification' then you can set the credential
</h4> </h4>
</div> </div>
</div> </div>

124
mail_push_notification/static/src/js/firebase.js

@ -1,89 +1,81 @@
/** @odoo-module **/ /** @odoo-module **/
import { jsonrpc } from "@web/core/network/rpc_service"; import { jsonrpc } from "@web/core/network/rpc_service";
/**
* Odoo module for handling Firebase push notifications. // Initialize variables
* let vapid = '';
* This module initializes Firebase messaging and handles push notifications let firebaseConfig = {};
* for the current session's company. It also registers the service worker for let messaging = null;
* handling notifications if the company has push notifications enabled. let push_notification = false;
*
* @module mail_push_notification // Fetch push notification settings for the current company
*/
var vapid = '';
var firebaseConfig = {};
var push_notification = false;
/**
* Sends an RPC query to retrieve push notification settings for the current company.
*
* @function
* @returns {Promise} A promise that resolves with the push notification settings.
*/
jsonrpc("/firebase_credentials", {}).then(function(data) { jsonrpc("/firebase_credentials", {}).then(function(data) {
if (data) { if (data && data.push_notification) {
if (data.push_notification) {
push_notification = true; push_notification = true;
if ("serviceWorker" in navigator) { if ("serviceWorker" in navigator) {
navigator.serviceWorker.register("/firebase-messaging-sw.js").then(function () {}); navigator.serviceWorker.register("/firebase-messaging-sw.js").then(function () {
} console.log('Service worker registered successfully.');
}).catch(function (err) {
console.error('Failed to register service worker:', err);
});
} }
} }
}); });
// Fetch Firebase configuration details
jsonrpc("/firebase_config_details", {}).then(function(data) { jsonrpc("/firebase_config_details", {}).then(function(data) {
if (data) { if (data) {
var json = JSON.parse(data); const json = JSON.parse(data);
vapid = json.vapid; vapid = json.vapid;
firebaseConfig = json.config; firebaseConfig = json.config;
/** // Initialize Firebase app with the retrieved configuration
* Initializes Firebase messaging and sets up event listeners for incoming messages.
*
* @function
*/
firebase.initializeApp(firebaseConfig); firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging(); messaging = firebase.messaging();
/** // Function to request notification permission and retrieve token
* Handles incoming push notification messages. function requestPermissionAndRetrieveToken() {
* console.log('not',Notification)
* @function Notification.requestPermission().then((permission) => {
* @param {Object} payload - The notification payload. console.log('permission',permission)
*/ if (permission === 'granted') {
messaging.onMessage((payload) => { console.log('Permission granted');
const notificationOptions = { // Retrieve registration token
body: payload.notification.body,
};
let notification = payload.notification;
navigator.serviceWorker.getRegistrations().then((registration) => {
registration[0].showNotification(notification.title, notificationOptions);
});
});
/**
* Requests permission for receiving push notifications and retrieves the registration token.
*
* @function
*/
messaging.requestPermission().then(function () {
/**
* Retrieves the registration token and sends it to the server for subscription.
*
* @function
* @param {string} vapidKey - The VAPID key for authentication.
*/
messaging.getToken({ vapidKey: vapid }).then((currentToken) => { messaging.getToken({ vapidKey: vapid }).then((currentToken) => {
console.log('Current token:', currentToken);
if (currentToken) { if (currentToken) {
/** // Send the token to the server for subscription
* Sends a POST request to the server with the registration token. $.post("/push_notification", { name: currentToken }).done(function(response) {
* console.log('Token sent to server:', response);
* @function }).fail(function(error) {
* @param {string} token - The registration token. console.error('Failed to send token to server:', error);
*/
$.post("/push_notification", {
name: currentToken
}); });
} else { } else {
console.log('No registration token found'); console.warn('No registration token available');
} }
}).catch((err) => { }).catch((err) => {
console.log('There is an error has occurred while attempting to retrieve the token.', err); console.error('Error retrieving token:', err);
});
} else {
console.warn('Permission for notifications was denied');
}
}).catch((err) => {
console.error('Unable to get permission to notify:', err);
});
}
// Initialize Firebase messaging and handle incoming messages
messaging.onMessage((payload) => {
// Show notification to user
const notificationTitle = payload.notification.title;
const notificationOptions = {
body: payload.notification.body,
icon: payload.notification.icon
};
navigator.serviceWorker.getRegistrations().then((registrations) => {
registrations[0].showNotification(notificationTitle, notificationOptions);
}).catch((err) => {
console.error('Error showing notification:', err);
});
}); });
// Request permission and retrieve token when the DOM content is loaded
document.addEventListener('DOMContentLoaded', (event) => {
requestPermissionAndRetrieveToken();
}); });
} }
}); });

55
mail_push_notification/views/res_config_settings_views.xml

@ -34,41 +34,62 @@
<div class="o_setting_left_pane"> <div class="o_setting_left_pane">
</div> </div>
<div class="o_setting_right_pane"> <div class="o_setting_right_pane">
<label for="server_key" <label for="project_id_firebase"
class="col-2 col-lg-2 o_light_label"/> class="col-2 col-lg-2 o_light_label"/>
<field name="server_key" <field name="project_id_firebase"
required="push_notification==True" required="push_notification==True"
password="1"/> password="1"/>
</div> </div>
<div class="o_setting_left_pane"> <div class="o_setting_left_pane">
</div> </div>
<div class="o_setting_right_pane"> <div class="o_setting_right_pane">
<label for="vapid" <label for="private_key_ref"
class="col-2 col-lg-2 o_light_label"/> class="col-2 col-lg-2 o_light_label"/>
<field name="vapid" <field name="private_key_ref"
required="push_notification == True" required="push_notification == True"
password="1"/> password="1"/>
</div> </div>
<div class="o_setting_left_pane"> <div class="o_setting_left_pane">
</div> </div>
<div class="o_setting_right_pane"> <div class="o_setting_right_pane">
<label for="api_key" <label for="private_key"
class="col-2 col-lg-2 o_light_label"/> class="col-2 col-lg-2 o_light_label"/>
<field name="api_key" <field name="private_key"
required="push_notification == True" required="push_notification == True"
password="1"/> password="1"/>
</div> </div>
<div class="o_setting_right_pane"> <div class="o_setting_right_pane">
<label for="auth_domain" <label for="client_email"
class="col-2 col-lg-2 o_light_label"/> class="col-2 col-lg-2 o_light_label"/>
<field name="auth_domain" <field name="client_email"
required="push_notification == True" required="push_notification == True"
password="1"/> password="1"/>
</div> </div>
<div class="o_setting_right_pane"> <div class="o_setting_right_pane">
<label for="project_id_firebase" <label for="client_id_firebase"
class="col-2 col-lg-2 o_light_label"/> class="col-2 col-lg-2 o_light_label"/>
<field name="project_id_firebase" <field name="client_id_firebase"
required="push_notification == True"
password="1"/>
</div>
<div class="o_setting_right_pane">
<label for="client_cert_url"
class="col-2 col-lg-2 o_light_label"/>
<field name="client_cert_url"
required="push_notification == True"
password="1"/>
</div>
<div class="o_setting_right_pane">
<label for="api_key"
class="col-2 col-lg-2 o_light_label"/>
<field name="api_key"
required="push_notification == True"
password="1"/>
</div>
<div class="o_setting_right_pane">
<label for="auth_domain"
class="col-2 col-lg-2 o_light_label"/>
<field name="auth_domain"
required="push_notification == True" required="push_notification == True"
password="1"/> password="1"/>
</div> </div>
@ -100,11 +121,15 @@
required="push_notification == True" required="push_notification == True"
password="1"/> password="1"/>
</div> </div>
<div class="col-lg-6 col-8 d-flex flex-row-reverse <div class="o_setting_right_pane">
o_setting_box"> <label for="vapid"
<button name="test_connection" class="col-2 col-lg-2 o_light_label"/>
string="Test Connection" <field name="vapid"
type="object" class="btn-primary"/> required="push_notification == True"
password="1"/>
</div>
<div class="col-lg-6 col-8 d-flex flex-row-reverse o_setting_box">
<button name="test_connection" string="Test Connection" type="object" class="btn-primary"/>
</div> </div>
</div> </div>
</div> </div>

Loading…
Cancel
Save