extend notifications
This commit is contained in:
parent
93e9a1990a
commit
c79a908281
@ -3,7 +3,7 @@ import sys
|
||||
from dotenv import load_dotenv
|
||||
import mysql.connector
|
||||
from datetime import datetime, timedelta
|
||||
from routes.api import send_notification
|
||||
from ktvmanager.lib.notifications import send_notification
|
||||
from ktvmanager.lib.database import get_push_subscriptions, _execute_query
|
||||
|
||||
# Add the project root to the Python path
|
||||
@ -33,41 +33,46 @@ def get_all_accounts(db_connection: MySQLConnection) -> List[Dict[str, Any]]:
|
||||
return accounts
|
||||
|
||||
|
||||
def send_expiry_notifications() -> None:
|
||||
def send_expiry_notifications(app) -> None:
|
||||
"""
|
||||
Sends notifications to users with accounts expiring in the next 30 days.
|
||||
"""
|
||||
now = datetime.now()
|
||||
thirty_days_later = now + timedelta(days=30)
|
||||
now_timestamp = int(now.timestamp())
|
||||
thirty_days_later_timestamp = int(thirty_days_later.timestamp())
|
||||
with app.app_context():
|
||||
now = datetime.now()
|
||||
thirty_days_later = now + timedelta(days=30)
|
||||
now_timestamp = int(now.timestamp())
|
||||
thirty_days_later_timestamp = int(thirty_days_later.timestamp())
|
||||
|
||||
query = """
|
||||
SELECT u.id as user_id, ua.username, ua.expiaryDate
|
||||
FROM users u
|
||||
JOIN userAccounts ua ON u.id = ua.userID
|
||||
WHERE ua.expiaryDate BETWEEN %s AND %s
|
||||
"""
|
||||
expiring_accounts = _execute_query(query, (now_timestamp, thirty_days_later_timestamp))
|
||||
query = """
|
||||
SELECT u.id as user_id, ua.username, ua.expiaryDate
|
||||
FROM users u
|
||||
JOIN userAccounts ua ON u.id = ua.userID
|
||||
WHERE ua.expiaryDate BETWEEN %s AND %s
|
||||
"""
|
||||
expiring_accounts = _execute_query(query, (now_timestamp, thirty_days_later_timestamp))
|
||||
|
||||
for account in expiring_accounts:
|
||||
user_id = account['user_id']
|
||||
subscriptions = get_push_subscriptions(user_id)
|
||||
for sub in subscriptions:
|
||||
# Check if a notification has been sent recently
|
||||
last_notified_query = "SELECT last_notified FROM push_subscriptions WHERE id = %s"
|
||||
last_notified_result = _execute_query(last_notified_query, (sub['id'],))
|
||||
last_notified = last_notified_result[0]['last_notified'] if last_notified_result and last_notified_result[0]['last_notified'] else None
|
||||
for account in expiring_accounts:
|
||||
expiry_date = datetime.fromtimestamp(account['expiaryDate'])
|
||||
days_to_expiry = (expiry_date - now).days
|
||||
|
||||
if last_notified and last_notified > now - timedelta(days=1):
|
||||
continue
|
||||
if days_to_expiry == 30 or days_to_expiry == 7:
|
||||
user_id = account['user_id']
|
||||
subscriptions = get_push_subscriptions(user_id)
|
||||
for sub in subscriptions:
|
||||
# Check if a notification has been sent recently
|
||||
last_notified_query = "SELECT last_notified FROM push_subscriptions WHERE id = %s"
|
||||
last_notified_result = _execute_query(last_notified_query, (sub['id'],))
|
||||
last_notified = last_notified_result[0]['last_notified'] if last_notified_result and last_notified_result[0]['last_notified'] else None
|
||||
|
||||
message = f"Your account {account['username']} is due to expire on {datetime.fromtimestamp(account['expiaryDate']).strftime('%d-%m-%Y')}."
|
||||
send_notification(sub['subscription_json'], message)
|
||||
if last_notified and last_notified.date() == now.date():
|
||||
continue
|
||||
|
||||
# Update the last notified timestamp
|
||||
update_last_notified_query = "UPDATE push_subscriptions SET last_notified = %s WHERE id = %s"
|
||||
_execute_query(update_last_notified_query, (now, sub['id']))
|
||||
message = f"Your account {account['username']} is due to expire in {days_to_expiry} days."
|
||||
send_notification(sub['subscription_json'], message)
|
||||
|
||||
# Update the last notified timestamp
|
||||
update_last_notified_query = "UPDATE push_subscriptions SET last_notified = %s WHERE id = %s"
|
||||
_execute_query(update_last_notified_query, (now, sub['id']))
|
||||
|
||||
|
||||
def main() -> None:
|
||||
|
17
ktvmanager/lib/notifications.py
Normal file
17
ktvmanager/lib/notifications.py
Normal file
@ -0,0 +1,17 @@
|
||||
from flask import current_app
|
||||
from pywebpush import webpush, WebPushException
|
||||
|
||||
def send_notification(subscription_info, message_body):
|
||||
try:
|
||||
webpush(
|
||||
subscription_info=subscription_info,
|
||||
data=message_body,
|
||||
vapid_private_key=current_app.config["VAPID_PRIVATE_KEY"],
|
||||
vapid_claims={"sub": current_app.config["VAPID_CLAIM_EMAIL"]},
|
||||
)
|
||||
except WebPushException as ex:
|
||||
print(f"Web push error: {ex}")
|
||||
# You might want to remove the subscription if it's invalid
|
||||
if ex.response and ex.response.status_code == 410:
|
||||
print("Subscription is no longer valid, removing from DB.")
|
||||
# Add logic to remove the subscription from your database
|
@ -4,6 +4,8 @@ from dotenv import load_dotenv
|
||||
from ktvmanager.config import DevelopmentConfig, ProductionConfig
|
||||
from routes.api import api_blueprint
|
||||
from ktvmanager.lib.database import initialize_db_pool
|
||||
from ktvmanager.account_checker import send_expiry_notifications
|
||||
from apscheduler.schedulers.background import BackgroundScheduler
|
||||
|
||||
def create_app():
|
||||
app = Flask(__name__)
|
||||
@ -17,6 +19,12 @@ def create_app():
|
||||
with app.app_context():
|
||||
initialize_db_pool()
|
||||
|
||||
# Schedule the daily account check
|
||||
scheduler = BackgroundScheduler()
|
||||
# Pass the app instance to the job
|
||||
scheduler.add_job(func=lambda: send_expiry_notifications(app), trigger="interval", days=1)
|
||||
scheduler.start()
|
||||
|
||||
# Register blueprints
|
||||
app.register_blueprint(api_blueprint)
|
||||
|
||||
|
@ -38,4 +38,5 @@ mysql-connector-python
|
||||
python-dotenv
|
||||
python-dotenv
|
||||
pywebpush==1.13.0
|
||||
stem==1.8.2
|
||||
stem==1.8.2
|
||||
APScheduler==3.10.4
|
@ -18,7 +18,7 @@ import re
|
||||
import base64
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from cryptography.hazmat.primitives.asymmetric import ec
|
||||
from pywebpush import webpush, WebPushException
|
||||
from ktvmanager.lib.notifications import send_notification
|
||||
|
||||
api_blueprint = Blueprint("api", __name__)
|
||||
|
||||
@ -196,20 +196,6 @@ def save_subscription(username: str, password: str) -> Response:
|
||||
return jsonify({"message": "Subscription saved."})
|
||||
|
||||
|
||||
def send_notification(subscription_info, message_body):
|
||||
try:
|
||||
webpush(
|
||||
subscription_info=subscription_info,
|
||||
data=message_body,
|
||||
vapid_private_key=current_app.config["VAPID_PRIVATE_KEY"],
|
||||
vapid_claims={"sub": current_app.config["VAPID_CLAIM_EMAIL"]},
|
||||
)
|
||||
except WebPushException as ex:
|
||||
print(f"Web push error: {ex}")
|
||||
# You might want to remove the subscription if it's invalid
|
||||
if ex.response and ex.response.status_code == 410:
|
||||
print("Subscription is no longer valid, removing from DB.")
|
||||
# Add logic to remove the subscription from your database
|
||||
|
||||
|
||||
@api_blueprint.route("/send-expiry-notifications", methods=["POST"])
|
||||
|
Loading…
x
Reference in New Issue
Block a user