feat: add push notification settings to user profile and update related functionality
All checks were successful
Chore App Build, Test, and Push Docker Images / build-and-push (push) Successful in 2m50s
All checks were successful
Chore App Build, Test, and Push Docker Images / build-and-push (push) Successful in 2m50s
This commit is contained in:
@@ -10,7 +10,7 @@ from api.pending_confirmation import PendingConfirmationResponse
|
||||
from api.reward_status import RewardStatus
|
||||
from api.utils import send_event_for_current_user, get_validated_user_id
|
||||
import api.child_action_helpers as chore_actions
|
||||
from db.db import child_db, task_db, reward_db, pending_reward_db, pending_confirmations_db
|
||||
from db.db import child_db, task_db, reward_db, pending_reward_db, pending_confirmations_db, users_db
|
||||
from db.tracking import insert_tracking_event
|
||||
from db.child_overrides import get_override, delete_override, delete_overrides_for_child
|
||||
from events.types.child_chore_confirmation import ChildChoreConfirmation
|
||||
@@ -929,25 +929,27 @@ def request_reward(id):
|
||||
send_event_for_current_user(Event(EventType.CHILD_REWARD_REQUEST.value, ChildRewardRequest(child.id, reward.id, ChildRewardRequest.REQUEST_CREATED)))
|
||||
|
||||
# Fire web push notification to all parent subscriptions
|
||||
try:
|
||||
approve_token = create_action_token(user_id, child.id, reward.id, 'reward', 'approve')
|
||||
deny_token = create_action_token(user_id, child.id, reward.id, 'reward', 'deny')
|
||||
push_payload = {
|
||||
'type': 'reward_requested',
|
||||
'title': f'{child.name} wants a reward',
|
||||
'body': f'{reward.name} costs {reward.cost} points.',
|
||||
'user_id': user_id,
|
||||
'child_id': child.id,
|
||||
'child_name': child.name,
|
||||
'entity_id': reward.id,
|
||||
'entity_type': 'reward',
|
||||
'entity_name': reward.name,
|
||||
'approve_token': approve_token.id,
|
||||
'deny_token': deny_token.id,
|
||||
}
|
||||
send_push_to_user(user_id, push_payload)
|
||||
except Exception as _push_err:
|
||||
logger.warning(f'Push notification failed for reward request: {_push_err}')
|
||||
_push_user = users_db.get(Query().id == user_id)
|
||||
if _push_user and _push_user.get('push_notifications_enabled', True):
|
||||
try:
|
||||
approve_token = create_action_token(user_id, child.id, reward.id, 'reward', 'approve')
|
||||
deny_token = create_action_token(user_id, child.id, reward.id, 'reward', 'deny')
|
||||
push_payload = {
|
||||
'type': 'reward_requested',
|
||||
'title': f'{child.name} wants a reward',
|
||||
'body': f'{reward.name} costs {reward.cost} points.',
|
||||
'user_id': user_id,
|
||||
'child_id': child.id,
|
||||
'child_name': child.name,
|
||||
'entity_id': reward.id,
|
||||
'entity_type': 'reward',
|
||||
'entity_name': reward.name,
|
||||
'approve_token': approve_token.id,
|
||||
'deny_token': deny_token.id,
|
||||
}
|
||||
send_push_to_user(user_id, push_payload)
|
||||
except Exception as _push_err:
|
||||
logger.warning(f'Push notification failed for reward request: {_push_err}')
|
||||
|
||||
return jsonify({
|
||||
'message': f'Reward request for {reward.name} submitted for {child.name}.',
|
||||
@@ -1139,25 +1141,27 @@ def confirm_chore(id):
|
||||
ChildChoreConfirmation(id, task_id, ChildChoreConfirmation.OPERATION_CONFIRMED)))
|
||||
|
||||
# Fire web push notification to all parent subscriptions
|
||||
try:
|
||||
approve_token = create_action_token(user_id, id, task_id, 'chore', 'approve')
|
||||
deny_token = create_action_token(user_id, id, task_id, 'chore', 'deny')
|
||||
push_payload = {
|
||||
'type': 'chore_confirmed',
|
||||
'title': f'{child.name} completed a chore',
|
||||
'body': f'{task.name} is waiting for your approval.',
|
||||
'user_id': user_id,
|
||||
'child_id': id,
|
||||
'child_name': child.name,
|
||||
'entity_id': task_id,
|
||||
'entity_type': 'chore',
|
||||
'entity_name': task.name,
|
||||
'approve_token': approve_token.id,
|
||||
'deny_token': deny_token.id,
|
||||
}
|
||||
send_push_to_user(user_id, push_payload)
|
||||
except Exception as _push_err:
|
||||
logger.warning(f'Push notification failed for chore confirmation: {_push_err}')
|
||||
_push_user = users_db.get(Query().id == user_id)
|
||||
if _push_user and _push_user.get('push_notifications_enabled', True):
|
||||
try:
|
||||
approve_token = create_action_token(user_id, id, task_id, 'chore', 'approve')
|
||||
deny_token = create_action_token(user_id, id, task_id, 'chore', 'deny')
|
||||
push_payload = {
|
||||
'type': 'chore_confirmed',
|
||||
'title': f'{child.name} completed a chore',
|
||||
'body': f'{task.name} is waiting for your approval.',
|
||||
'user_id': user_id,
|
||||
'child_id': id,
|
||||
'child_name': child.name,
|
||||
'entity_id': task_id,
|
||||
'entity_type': 'chore',
|
||||
'entity_name': task.name,
|
||||
'approve_token': approve_token.id,
|
||||
'deny_token': deny_token.id,
|
||||
}
|
||||
send_push_to_user(user_id, push_payload)
|
||||
except Exception as _push_err:
|
||||
logger.warning(f'Push notification failed for chore confirmation: {_push_err}')
|
||||
|
||||
return jsonify({'message': f'Chore {task.name} confirmed by {child.name}.', 'confirmation_id': confirmation.id}), 200
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ def get_profile():
|
||||
'email': user.email,
|
||||
'image_id': user.image_id,
|
||||
'email_digest_enabled': user.email_digest_enabled,
|
||||
'push_notifications_enabled': user.push_notifications_enabled,
|
||||
}), 200
|
||||
|
||||
@user_api.route('/user/profile', methods=['PUT'])
|
||||
@@ -59,11 +60,12 @@ def update_profile():
|
||||
if not user:
|
||||
return jsonify({'error': 'Unauthorized'}), 401
|
||||
data = request.get_json()
|
||||
# Only allow first_name, last_name, image_id, email_digest_enabled to be updated
|
||||
# Only allow first_name, last_name, image_id, email_digest_enabled, push_notifications_enabled to be updated
|
||||
first_name = data.get('first_name')
|
||||
last_name = data.get('last_name')
|
||||
image_id = data.get('image_id')
|
||||
email_digest_enabled = data.get('email_digest_enabled')
|
||||
push_notifications_enabled = data.get('push_notifications_enabled')
|
||||
if first_name is not None:
|
||||
user.first_name = first_name
|
||||
if last_name is not None:
|
||||
@@ -72,6 +74,8 @@ def update_profile():
|
||||
user.image_id = image_id
|
||||
if email_digest_enabled is not None:
|
||||
user.email_digest_enabled = bool(email_digest_enabled)
|
||||
if push_notifications_enabled is not None:
|
||||
user.push_notifications_enabled = bool(push_notifications_enabled)
|
||||
users_db.update(user.to_dict(), UserQuery.email == user.email)
|
||||
|
||||
# Create tracking event
|
||||
@@ -84,6 +88,8 @@ def update_profile():
|
||||
metadata['image_updated'] = True
|
||||
if email_digest_enabled is not None:
|
||||
metadata['email_digest_enabled_updated'] = True
|
||||
if push_notifications_enabled is not None:
|
||||
metadata['push_notifications_enabled_updated'] = True
|
||||
|
||||
tracking_event = TrackingEvent.create_event(
|
||||
user_id=user_id,
|
||||
|
||||
@@ -24,6 +24,7 @@ class User(BaseModel):
|
||||
token_version: int = 0
|
||||
timezone: str | None = None
|
||||
email_digest_enabled: bool = True
|
||||
push_notifications_enabled: bool = True
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, d: dict):
|
||||
@@ -49,6 +50,7 @@ class User(BaseModel):
|
||||
token_version=d.get('token_version', 0),
|
||||
timezone=d.get('timezone'),
|
||||
email_digest_enabled=d.get('email_digest_enabled', True),
|
||||
push_notifications_enabled=d.get('push_notifications_enabled', True),
|
||||
id=d.get('id'),
|
||||
created_at=d.get('created_at'),
|
||||
updated_at=d.get('updated_at')
|
||||
@@ -79,5 +81,6 @@ class User(BaseModel):
|
||||
'token_version': self.token_version,
|
||||
'timezone': self.timezone,
|
||||
'email_digest_enabled': self.email_digest_enabled,
|
||||
'push_notifications_enabled': self.push_notifications_enabled,
|
||||
})
|
||||
return base
|
||||
|
||||
Reference in New Issue
Block a user