@ -43,7 +43,7 @@ class WebPushService():
# Setting the application instance
# Setting the application instance
self . app = app
self . app = app
self . app . add_url_rule ( ' /web-push/regenerate_ vapid ' , view_func = self . regenerate_vapid , methods = [ ' POST ' ] )
self . app . add_url_rule ( ' /web-push/regenerate- vapid ' , view_func = self . regenerate_vapid , methods = [ ' POST ' ] )
# Setting the database URI for the application
# Setting the database URI for the application
db_uri = os . getenv ( ' SQLALCHEMY_DATABASE_URI ' , ' sqlite:////app/instance/data/webpush.db ' )
db_uri = os . getenv ( ' SQLALCHEMY_DATABASE_URI ' , ' sqlite:////app/instance/data/webpush.db ' )
@ -102,7 +102,8 @@ class WebPushService():
db . session . commit ( )
db . session . commit ( )
except Exception as e :
except Exception as e :
print ( f " Error generating VAPID keys: { e } " )
print ( f " Error generating VAPID keys: { str ( e ) } " )
raise e
def _initialize ( self ) - > None :
def _initialize ( self ) - > None :
@ -135,7 +136,8 @@ class WebPushService():
- vapid_key ( VAPIDKey ) : The VAPID key model instance containing the private key used for sending the notification .
- vapid_key ( VAPIDKey ) : The VAPID key model instance containing the private key used for sending the notification .
Returns :
Returns :
- bool : True if the push notification was sent successfully , False otherwise .
- request . Response https : / / requests . readthedocs . io / en / latest / api . html #requests.Response if the push notification was sent successfully
or False if there was an exception
Notes :
Notes :
- The ` webpush ` function is used to send the notification .
- The ` webpush ` function is used to send the notification .
@ -144,14 +146,15 @@ class WebPushService():
# Sending the push notification using the webpush function
# Sending the push notification using the webpush function
try :
try :
webpush (
result = webpush (
subscription_info = subscription_info ,
subscription_info = subscription_info ,
data = json . dumps ( message ) ,
data = json . dumps ( message ) ,
vapid_private_key = vapid_key . private_key ,
vapid_private_key = vapid_key . private_key ,
vapid_claims = { " sub " : CONTACT_EMAIL }
vapid_claims = { " sub " : CONTACT_EMAIL }
)
)
# "because sometimes that's what I had to do to make it work!" - Matthew
time . sleep ( 1 )
time . sleep ( 1 )
return True
return { " success " : True , " message " : result . text , " result " : result }
except WebPushException as ex :
except WebPushException as ex :
now = datetime . datetime . now ( ) . isoformat ( )
now = datetime . datetime . now ( ) . isoformat ( )
@ -172,7 +175,7 @@ class WebPushService():
else :
else :
print ( " Error other than unsubscribed/expired. " , ex . args [ 0 ] , flush = True )
print ( " Error other than unsubscribed/expired. " , ex . args [ 0 ] , flush = True )
return False
return { " success " : False , " message " : ex . args [ 0 ] }
def _send_daily_notifications ( self ) - > None :
def _send_daily_notifications ( self ) - > None :
@ -234,19 +237,19 @@ class WebPushService():
1. Deletes the current VAPID keys from the database .
1. Deletes the current VAPID keys from the database .
2. Generates and stores new VAPID keys using the ` _generate_and_save_vapid_keys ` method .
2. Generates and stores new VAPID keys using the ` _generate_and_save_vapid_keys ` method .
URL : / web - push / regenerate_ vapid
URL : / web - push / regenerate - vapid
Method : POST
Method : POST
Header : Authentication : Basic . . .
Header : Authentication : Basic . . .
Returns :
Returns :
- Tuple [ str , int ] : A JSON response indicating the success or failure of the operation , along with the appropriate HTTP status code .
- tuple with " success " as True or False , and " message " message string
Notes :
Notes :
- If the operation is successful , a JSON response with a success message is returned with a 200 status code .
- If the operation is successful , a JSON response with a success message is returned with a 200 status code .
- If there ' s an error during the operation, a JSON response with the error message is returned with a 500 status code.
- If there ' s an error during the operation, a JSON response with the error message is returned with a 500 status code.
"""
"""
# This default can be invoked thus: curl -X POST -H "Authorization: Basic YWRtaW46YWRtaW4=" localhost:3000/web-push/regenerate_ vapid
# This default can be invoked thus: curl -X POST -H "Authorization: Basic YWRtaW46YWRtaW4=" localhost:3000/web-push/regenerate- vapid
envPassword = os . getenv ( ' ADMIN_PASSWORD ' , ' admin ' )
envPassword = os . getenv ( ' ADMIN_PASSWORD ' , ' admin ' )
auth = request . authorization
auth = request . authorization
if ( auth is None
if ( auth is None
@ -273,7 +276,7 @@ class WebPushService():
return jsonify ( success = True , message = " VAPID keys regenerated successfully " ) , 200
return jsonify ( success = True , message = " VAPID keys regenerated successfully " ) , 200
except Exception as e :
except Exception as e :
return jsonify ( error = f ' Error regenerating VAPID keys: { str ( e ) } ' ) , 500
return jsonify ( success = False , message = f ' Error regenerating VAPID keys: { str ( e ) } ' ) , 500
@staticmethod
@staticmethod
@ -317,7 +320,7 @@ class WebPushService():
Method : POST
Method : POST
Returns :
Returns :
- Tuple [ str , int ] : A JSON response indicating the success or failure of the operation , along with the appropriate HTTP status code .
- A JSON response with " success " as True or False , " message " as a response message string , and potentially a " result " as a request . Response object from sending a test notification
Notes :
Notes :
- If the operation is successful , a confirmation push notification is sent to the subscriber with a success message .
- If the operation is successful , a confirmation push notification is sent to the subscriber with a success message .
@ -333,7 +336,7 @@ class WebPushService():
# Checking if the VAPID key is available
# Checking if the VAPID key is available
if not vapid_key :
if not vapid_key :
return jsonify ( success = False , error = " No VAPID keys available " ) , 500
return jsonify ( success = False , message = " No VAPID keys available " ) , 500
# Creating a new Subscription instance with the provided data
# Creating a new Subscription instance with the provided data
subscription = Subscription ( endpoint = content [ ' endpoint ' ] ,
subscription = Subscription ( endpoint = content [ ' endpoint ' ] ,
@ -361,10 +364,10 @@ class WebPushService():
message = { " title " : " Subscription Successful " , " message " : " Thank you for subscribing! " }
message = { " title " : " Subscription Successful " , " message " : " Thank you for subscribing! " }
# Sending the confirmation push notification
# Sending the confirmation push notification
success = WebPushService . _send_push_notification ( subscription_info , message , vapid_key )
result = WebPushService . _send_push_notification ( subscription_info , message , vapid_key )
# Returning the operation status
# Returning the operation status
return jsonify ( success = succ ess )
return jsonify ( success = re sult [ " status_cod e" ] == 201 , message = result [ " text " ] )
@staticmethod
@staticmethod
@ -404,7 +407,69 @@ class WebPushService():
# If the subscription is not found, return an error message
# If the subscription is not found, return an error message
else :
else :
return jsonify ( success = False , error = " Subscription not found " ) , 404
return jsonify ( success = False , message = " Subscription not found " ) , 404
@staticmethod
@app . route ( ' /web-push/send-test ' , methods = [ ' POST ' ] )
def send_test ( ) - > Tuple [ str , int ] :
"""
Endpoint to send a test push notification to a specific client .
This method :
1. Retrieves the subscription information from the incoming request .
2. Looks up the subscription in the database .
3. Calls the _send_push_notification method to send a test push notification .
4. Returns the result of the _send_push_notification call .
URL : / web - push / send - test
Method : POST
Returns :
- A JSON response with the result of the _send_push_notification call .
Notes :
- The incoming request should contain the parameters " endpoint " , " p256dh " , and " auth " .
"""
# Retrieving the subscription information from the incoming request
content = request . json
endpoint = content [ ' endpoint ' ]
p256dh = content [ ' keys ' ] [ ' p256dh ' ]
auth = content [ ' keys ' ] [ ' auth ' ]
# Looking up the subscription in the database
subscription = Subscription . query . filter_by ( endpoint = endpoint , p256dh = p256dh , auth = auth ) . first ( )
# If the subscription is found, call the _send_push_notification method
if subscription :
subscription_info = {
" endpoint " : subscription . endpoint ,
" keys " : {
" p256dh " : subscription . p256dh ,
" auth " : subscription . auth
}
}
title = " Test Notification "
if " title " in content :
title = content [ ' title ' ]
message = " This is a test notification. "
if " message " in content :
message = content [ ' message ' ]
vapid_key = VAPIDKey . query . filter_by ( id = subscription . vapid_key_id ) . first ( )
result = WebPushService . _send_push_notification (
subscription_info ,
{ " title " : title , " message " : message } ,
vapid_key
)
return jsonify (
success = result [ " result " ] . status_code == 201 ,
message = result [ " result " ] . text ,
)
else :
return jsonify ( { " success " : False , " message " : " Subscription not found " } ) , 404
web_push_service = WebPushService ( app , " app " )
web_push_service = WebPushService ( app , " app " )