Allow to disable certain notification type

This commit is contained in:
Thomas Sileo 2022-11-27 12:11:42 +01:00
parent e30e0de10e
commit ec36272bb4
4 changed files with 167 additions and 98 deletions

View file

@ -50,6 +50,17 @@ from app.utils.text import slugify
AnyboxObject = models.InboxObject | models.OutboxObject AnyboxObject = models.InboxObject | models.OutboxObject
def is_notification_enabled(notification_type: models.NotificationType) -> bool:
"""Checks if a given notification type is enabled."""
if notification_type.value == "pending_incoming_follower":
# This one cannot be disabled as it would prevent manually reviewing
# follow requests.
return True
if notification_type.value in config.CONFIG.disabled_notifications:
return False
return True
def allocate_outbox_id() -> str: def allocate_outbox_id() -> str:
return uuid.uuid4().hex return uuid.uuid4().hex
@ -168,6 +179,7 @@ async def send_block(db_session: AsyncSession, ap_actor_id: str) -> None:
await new_outgoing_activity(db_session, actor.inbox_url, outbox_object.id) await new_outgoing_activity(db_session, actor.inbox_url, outbox_object.id)
# 4. Create a notification # 4. Create a notification
if is_notification_enabled(models.NotificationType.BLOCK):
notif = models.Notification( notif = models.Notification(
notification_type=models.NotificationType.BLOCK, notification_type=models.NotificationType.BLOCK,
actor_id=actor.id, actor_id=actor.id,
@ -447,6 +459,7 @@ async def _send_undo(db_session: AsyncSession, ap_object_id: str) -> None:
outbox_object.id, outbox_object.id,
) )
if is_notification_enabled(models.NotificationType.UNBLOCK):
notif = models.Notification( notif = models.Notification(
notification_type=models.NotificationType.UNBLOCK, notification_type=models.NotificationType.UNBLOCK,
actor_id=blocked_actor.id, actor_id=blocked_actor.id,
@ -1525,6 +1538,7 @@ async def _send_accept(
raise ValueError("Should never happen") raise ValueError("Should never happen")
await new_outgoing_activity(db_session, from_actor.inbox_url, outbox_activity.id) await new_outgoing_activity(db_session, from_actor.inbox_url, outbox_activity.id)
if is_notification_enabled(models.NotificationType.NEW_FOLLOWER):
notif = models.Notification( notif = models.Notification(
notification_type=models.NotificationType.NEW_FOLLOWER, notification_type=models.NotificationType.NEW_FOLLOWER,
actor_id=from_actor.id, actor_id=from_actor.id,
@ -1568,6 +1582,7 @@ async def _send_reject(
raise ValueError("Should never happen") raise ValueError("Should never happen")
await new_outgoing_activity(db_session, from_actor.inbox_url, outbox_activity.id) await new_outgoing_activity(db_session, from_actor.inbox_url, outbox_activity.id)
if is_notification_enabled(models.NotificationType.REJECTED_FOLLOWER):
notif = models.Notification( notif = models.Notification(
notification_type=models.NotificationType.REJECTED_FOLLOWER, notification_type=models.NotificationType.REJECTED_FOLLOWER,
actor_id=from_actor.id, actor_id=from_actor.id,
@ -1598,6 +1613,7 @@ async def _handle_undo_activity(
models.Follower.inbox_object_id == ap_activity_to_undo.id models.Follower.inbox_object_id == ap_activity_to_undo.id
) )
) )
if is_notification_enabled(models.NotificationType.UNFOLLOW):
notif = models.Notification( notif = models.Notification(
notification_type=models.NotificationType.UNFOLLOW, notification_type=models.NotificationType.UNFOLLOW,
actor_id=from_actor.id, actor_id=from_actor.id,
@ -1618,7 +1634,14 @@ async def _handle_undo_activity(
) )
return return
liked_obj.likes_count = models.OutboxObject.likes_count - 1 liked_obj.likes_count = (
await _get_outbox_likes_count(
db_session,
liked_obj,
)
- 1
)
if is_notification_enabled(models.NotificationType.UNDO_LIKE):
notif = models.Notification( notif = models.Notification(
notification_type=models.NotificationType.UNDO_LIKE, notification_type=models.NotificationType.UNDO_LIKE,
actor_id=from_actor.id, actor_id=from_actor.id,
@ -1643,6 +1666,7 @@ async def _handle_undo_activity(
announced_obj_from_outbox.announces_count = ( announced_obj_from_outbox.announces_count = (
models.OutboxObject.announces_count - 1 models.OutboxObject.announces_count - 1
) )
if is_notification_enabled(models.NotificationType.UNDO_ANNOUNCE):
notif = models.Notification( notif = models.Notification(
notification_type=models.NotificationType.UNDO_ANNOUNCE, notification_type=models.NotificationType.UNDO_ANNOUNCE,
actor_id=from_actor.id, actor_id=from_actor.id,
@ -1651,6 +1675,7 @@ async def _handle_undo_activity(
) )
db_session.add(notif) db_session.add(notif)
elif ap_activity_to_undo.ap_type == "Block": elif ap_activity_to_undo.ap_type == "Block":
if is_notification_enabled(models.NotificationType.UNBLOCKED):
notif = models.Notification( notif = models.Notification(
notification_type=models.NotificationType.UNBLOCKED, notification_type=models.NotificationType.UNBLOCKED,
actor_id=from_actor.id, actor_id=from_actor.id,
@ -1720,6 +1745,7 @@ async def _handle_move_activity(
else: else:
logger.info(f"Already following target {new_actor_id}") logger.info(f"Already following target {new_actor_id}")
if is_notification_enabled(models.NotificationType.MOVE):
notif = models.Notification( notif = models.Notification(
notification_type=models.NotificationType.MOVE, notification_type=models.NotificationType.MOVE,
actor_id=new_actor.id, actor_id=new_actor.id,
@ -1999,7 +2025,7 @@ async def _process_note_object(
inbox_object_id=parent_activity.id, inbox_object_id=parent_activity.id,
) )
if is_mention: if is_mention and is_notification_enabled(models.NotificationType.MENTION):
notif = models.Notification( notif = models.Notification(
notification_type=models.NotificationType.MENTION, notification_type=models.NotificationType.MENTION,
actor_id=from_actor.id, actor_id=from_actor.id,
@ -2098,6 +2124,7 @@ async def _handle_announce_activity(
models.OutboxObject.announces_count + 1 models.OutboxObject.announces_count + 1
) )
if is_notification_enabled(models.NotificationType.ANNOUNCE):
notif = models.Notification( notif = models.Notification(
notification_type=models.NotificationType.ANNOUNCE, notification_type=models.NotificationType.ANNOUNCE,
actor_id=actor.id, actor_id=actor.id,
@ -2202,6 +2229,7 @@ async def _handle_like_activity(
relates_to_outbox_object, relates_to_outbox_object,
) )
if is_notification_enabled(models.NotificationType.LIKE):
notif = models.Notification( notif = models.Notification(
notification_type=models.NotificationType.LIKE, notification_type=models.NotificationType.LIKE,
actor_id=actor.id, actor_id=actor.id,
@ -2225,6 +2253,7 @@ async def _handle_block_activity(
return return
# Create a notification # Create a notification
if is_notification_enabled(models.NotificationType.BLOCKED):
notif = models.Notification( notif = models.Notification(
notification_type=models.NotificationType.BLOCKED, notification_type=models.NotificationType.BLOCKED,
actor_id=actor.id, actor_id=actor.id,
@ -2433,6 +2462,7 @@ async def save_to_inbox(
if activity_ro.ap_type == "Accept" if activity_ro.ap_type == "Accept"
else models.NotificationType.FOLLOW_REQUEST_REJECTED else models.NotificationType.FOLLOW_REQUEST_REJECTED
) )
if is_notification_enabled(notif_type):
notif = models.Notification( notif = models.Notification(
notification_type=notif_type, notification_type=notif_type,
actor_id=actor.id, actor_id=actor.id,

View file

@ -120,6 +120,8 @@ class Config(pydantic.BaseModel):
session_timeout: int = 3600 * 24 * 3 # in seconds, 3 days by default session_timeout: int = 3600 * 24 * 3 # in seconds, 3 days by default
disabled_notifications: list[str] = []
# Only set when the app is served on a non-root path # Only set when the app is served on a non-root path
id: str | None = None id: str | None = None

View file

@ -17,6 +17,7 @@ from app.boxes import _get_outbox_likes_count
from app.boxes import _get_outbox_replies_count from app.boxes import _get_outbox_replies_count
from app.boxes import get_outbox_object_by_ap_id from app.boxes import get_outbox_object_by_ap_id
from app.boxes import get_outbox_object_by_slug_and_short_id from app.boxes import get_outbox_object_by_slug_and_short_id
from app.boxes import is_notification_enabled
from app.database import AsyncSession from app.database import AsyncSession
from app.database import get_db_session from app.database import get_db_session
from app.utils import microformats from app.utils import microformats
@ -118,6 +119,7 @@ async def webmention_endpoint(
db_session, existing_webmention_in_db, mentioned_object db_session, existing_webmention_in_db, mentioned_object
) )
if is_notification_enabled(models.NotificationType.DELETED_WEBMENTION):
notif = models.Notification( notif = models.Notification(
notification_type=models.NotificationType.DELETED_WEBMENTION, notification_type=models.NotificationType.DELETED_WEBMENTION,
outbox_object_id=mentioned_object.id, outbox_object_id=mentioned_object.id,
@ -144,6 +146,7 @@ async def webmention_endpoint(
await db_session.flush() await db_session.flush()
webmention = existing_webmention_in_db webmention = existing_webmention_in_db
if is_notification_enabled(models.NotificationType.UPDATED_WEBMENTION):
notif = models.Notification( notif = models.Notification(
notification_type=models.NotificationType.UPDATED_WEBMENTION, notification_type=models.NotificationType.UPDATED_WEBMENTION,
outbox_object_id=mentioned_object.id, outbox_object_id=mentioned_object.id,
@ -162,6 +165,7 @@ async def webmention_endpoint(
await db_session.flush() await db_session.flush()
webmention = new_webmention webmention = new_webmention
if is_notification_enabled(models.NotificationType.NEW_WEBMENTION):
notif = models.Notification( notif = models.Notification(
notification_type=models.NotificationType.NEW_WEBMENTION, notification_type=models.NotificationType.NEW_WEBMENTION,
outbox_object_id=mentioned_object.id, outbox_object_id=mentioned_object.id,

View file

@ -98,6 +98,39 @@ privacy_replace = [
] ]
``` ```
### Disabling certain notification types
All notifications are enabled by default.
You can disabled specific notifications by adding them to the `disabled_notifications` list.
This example disables likes and shares notifications:
```
disabled_notifications = ["like", "announce"]
```
#### Available notification types
- `new_follower`
- `rejected_follower`
- `unfollow`
- `follow_request_accepted`
- `follow_request_rejected`
- `move`
- `like`
- `undo_like`
- `announce`
- `undo_announce`
- `mention`
- `new_webmention`
- `updated_webmention`
- `deleted_webmention`
- `blocked`
- `unblocked`
- `block`
- `unblock`
### Customization ### Customization
#### Default emoji #### Default emoji